2012-07-08 15 views
20

के साथ जावाएफएक्स नियंत्रक का परीक्षण कैसे करते हैं जावाफैक्स रनटाइम को प्रारंभ करने का सही तरीका क्या है ताकि आप यूनिट टेस्ट (जुनीट के साथ) नियंत्रक कर सकें जो समवर्ती सुविधाओं और Platform.runLater(Runnable) का उपयोग करते हैं?आप JUnit

@BeforeClass से कॉलिंग परिणाम मृत लॉक में परिणाम। यदि Application.launch(...) तो नहीं बुलाया जाता है निम्न त्रुटि फेंक दिया जाता है:


java.lang.IllegalStateException: Toolkit not initialized 
    at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:121) 
    at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:116) 
    at javafx.application.Platform.runLater(Platform.java:52) 
    at javafx.concurrent.Task.runLater(Task.java:1042) 
    at javafx.concurrent.Task.updateMessage(Task.java:987) 
    at com.xyz.AudioSegmentExtractor.call(AudioSegmentExtractor.java:64) 
    at com.xyz.CompletionControllerTest.setUp(CompletionControllerTest.java:69) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

फॉलोअप: इस मूल भाव मैं @SergeyGrinev द्वारा की गई अनुशंसाओं पर आधारित का उपयोग किया है।

... // Inside test class 

public static class AsNonApp extends Application { 
    @Override 
    public void start(Stage primaryStage) throws Exception { 
     // noop 
    } 
} 

@BeforeClass 
public static void initJFX() { 
    Thread t = new Thread("JavaFX Init Thread") { 
     public void run() { 
      Application.launch(AsNonApp.class, new String[0]); 
     } 
    }; 
    t.setDaemon(true); 
    t.start(); 
} 
... // controller tests follow... 

उत्तर

14

@BeforeClass से launch() कॉलिंग एक सही तरीका है। बस ध्यान दें कि launch() कॉलिंग कोड पर नियंत्रण नहीं लौटाता है। तो आपको इसे new Thread(...).start() में लपेटना होगा।

7

मुझे यह काम करने के लिए मिला, ... लेकिन जावाफैक्स एप्लिकेशन थ्रेड शुरू करने के बाद केवल थ्रेड.sleep (500) जोड़ने के बाद। मुमकिन है यह (पर मेरे मैकबुक प्रो रेटिना के बारे में 200 मि.से) FX वातावरण और तैयार होने के लिए कुछ समय लगता है

@BeforeClass 
public static void setUpClass() throws InterruptedException { 
    // Initialise Java FX 

    System.out.printf("About to launch FX App\n"); 
    Thread t = new Thread("JavaFX Init Thread") { 
     public void run() { 
      Application.launch(AsNonApp.class, new String[0]); 
     } 
    }; 
    t.setDaemon(true); 
    t.start(); 
    System.out.printf("FX App thread started\n"); 
    Thread.sleep(500); 
} 
+3

[Application.launch] (यह या एक से अधिक बार नहीं कहा जाना चाहिए एक अपवाद फेंक दिया जाएगा।) प्रलेखन कहता है: "इसे एक से अधिक बार नहीं कहा जाना चाहिए या अपवाद फेंक दिया जाएगा।", अगर आप इस उत्तर में setUpClass() विधि को एक से अधिक बार चलाने का प्रयास करते हैं तो बस कुछ पता होना चाहिए। – jewelsea