2016-09-01 10 views
2

私はJavaFXでSpring Bootを使用してテストしています(これについて説明しているsome excellent YouTube videosに基づいています)。このために私が使用して、私は今、このJavaFXアプリケーションをテストしたいSpringブートテストで 'ヘッドレス'プロパティを設定する方法は?

@Override 
public void init() throws Exception { 
    SpringApplicationBuilder builder = new SpringApplicationBuilder(MyJavaFXApplication.class); 
    builder.headless(false); // Needed for TestFX 
    context = builder.run(getParameters().getRaw().stream().toArray(String[]::new)); 

    FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml")); 
    loader.setControllerFactory(context::getBean); 
    rootNode = loader.load(); 
} 

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) 
public class MyJavaFXApplicationUITest extends TestFXBase { 

    @MockBean 
    private MachineService machineService; 

    @Test 
    public void test() throws InterruptedException { 
     WaitForAsyncUtils.waitForFxEvents(); 
     verifyThat("#statusText", (Text text) -> text.getText().equals("Machine stopped")); 
     clickOn("#startMachineButton"); 
     verifyThat("#startMachineButton", Node::isDisabled); 
     verifyThat("#statusText", (Text text) -> text.getText().equals("Machine started")); 
    } 
} 

これは始まり

はそれがTestFXで動作させるために、私はこのような状況を作成する必要がありますSpringコンテキストを使用して、「通常の」Beanを模擬Beanに置き換えます。

しかし、通常の起動時にこの「ヘッドレス」プロパティがfalseに設定されていないため、今度はjava.awt.HeadlessExceptionになります。テスト中にこのプロパティを設定する方法は?

EDIT:

が探し近い春のテストフレームワークを開始すると、私はinit方法で手動で作成する1、そのテスト対象のアプリケーションが嘲笑豆を使用していないことを1、2コンテキストが開始さがあるようです。誰かがinit()メソッドでテストコンテキストリファレンスを取得する方法を手がかりにしている場合、私は非常に満足しています。

+1

これは可能です[リンク](http://stackoverflow.com/questions/36160353/why-does-swing-think-its-headless-under-spring-boot-but-not-under-spring-or- pl)があなたを助けます。 –

答えて

3

Praveen Kumarからのコメントは良い方向を指していました。 -Djava.awt.headless=falseでテストを実行すると例外はありません。

これはあなたのメインのJavaFX起動クラスであると仮定します:

は2つの春のコンテキストの他の問題を解決するために、私は次のようにしなければならなかった

@SpringBootApplication 
    public class MyJavaFXClientApplication extends Application { 

    private ConfigurableApplicationContext context; 
    private Parent rootNode; 

    @Override 
    public void init() throws Exception { 
     SpringApplicationBuilder builder = new SpringApplicationBuilder(MyJavaFXClientApplication.class); 
     builder.headless(false); // Needed for TestFX 
     context = builder.run(getParameters().getRaw().stream().toArray(String[]::new)); 

     FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml")); 
     loader.setControllerFactory(context::getBean); 
     rootNode = loader.load(); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds(); 
     double width = visualBounds.getWidth(); 
     double height = visualBounds.getHeight(); 

     primaryStage.setScene(new Scene(rootNode, width, height)); 
     primaryStage.centerOnScreen(); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     Application.launch(args); 
    } 

    @Override 
    public void stop() throws Exception { 
     context.close(); 
    } 

    public void setContext(ConfigurableApplicationContext context) { 
     this.context = context; 
    } 
} 

とテストのために、あなたはこの抽象を使用基底クラス(Courtesy of this YouTube video by MVP Java):

public abstract class TestFXBase extends ApplicationTest { 

    @BeforeClass 
    public static void setupHeadlessMode() { 
     if (Boolean.getBoolean("headless")) { 
      System.setProperty("testfx.robot", "glass"); 
      System.setProperty("testfx.headless", "true"); 
      System.setProperty("prism.order", "sw"); 
      System.setProperty("prism.text", "t2k"); 
      System.setProperty("java.awt.headless", "true"); 
     } 
    } 

    @After 
    public void afterEachTest() throws TimeoutException { 
     FxToolkit.hideStage(); 
     release(new KeyCode[0]); 
     release(new MouseButton[0]); 
    } 

    @SuppressWarnings("unchecked") 
    public <T extends Node> T find(String query, Class<T> clazz) { 
     return (T) lookup(query).queryAll().iterator().next(); 
    } 
} 

次に、あなたがこのようなテストを書くことができます

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) 
public class MyJavaFXApplicationUITest extends TestFXBase { 

    @MockBean 
    private TemperatureService temperatureService; 

    @Autowired 
    private ConfigurableApplicationContext context; 

    @Override 
    public void start(Stage stage) throws Exception { 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml")); 
     loader.setControllerFactory(context::getBean); 
     Parent rootNode = loader.load(); 

     stage.setScene(new Scene(rootNode, 800, 600)); 
     stage.centerOnScreen(); 
     stage.show(); 
    } 

    @Test 
    public void testTemperatureReading() throws InterruptedException { 
     when(temperatureService.getCurrentTemperature()).thenReturn(new Temperature(25.0)); 
     WaitForAsyncUtils.waitForFxEvents(); 

     assertThat(find("#temperatureText", Text.class).getText()).isEqualTo("25.00 C"); 
    } 
} 

これにより、模擬サービスを使用してUIを開始することができます。

関連する問題