Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何设置';无头';Spring启动测试中的属性?_Java_Javafx_Spring Boot_Spring Test_Testfx - Fatal编程技术网

Java 如何设置';无头';Spring启动测试中的属性?

Java 如何设置';无头';Spring启动测试中的属性?,java,javafx,spring-boot,spring-test,testfx,Java,Javafx,Spring Boot,Spring Test,Testfx,我正在使用SpringBoot和JavaFX进行测试(基于这一点,我可以解释这一点) 要使其工作,我需要创建如下上下文: @Override public void init() throws Exception { SpringApplicationBuilder builder = new SpringApplicationBuilder(MyJavaFXApplication.class); builder.headless(false); // Needed for Te

我正在使用SpringBoot和JavaFX进行测试(基于这一点,我可以解释这一点)

要使其工作,我需要创建如下上下文:

@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 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");
    }
}
现在我想测试这个JavaFX应用程序,为此我使用:

@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"));
    }
}
这将启动一个Spring上下文,并按预期用模拟bean替换“普通”bean

但是,我现在得到了一个
java.awt.HeadlessException
,因为这个“headless”属性没有设置为false,就像在正常启动时那样。如何在测试期间设置此属性

编辑:


仔细看,似乎有两个上下文启动了,一个是Spring测试框架启动的,另一个是我在
init
方法中手动创建的,因此被测试的应用程序没有使用模拟bean。如果有人知道如何在
init()
方法中获取测试上下文引用,我将非常高兴。

Praveen Kumar的评论指出了好的方向。当我使用
-Djava.awt.headless=false运行测试时,没有异常

为了解决2个Spring上下文中的另一个问题,我必须执行以下操作:

假设这是您的主要JavaFx启动类:

    @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;
    }
}
对于测试,您可以使用这个抽象基类():


这允许使用模拟服务启动UI。

SpringBootTest使用SpringBootContextLoader类作为上下文加载程序,因此应用程序上下文从方法
SpringBootContextLoader.loadContext
加载如下:

SpringApplication application = getSpringApplication();
......
return application.run();
调用方法
application.run()
时,应用程序使用其内部headless属性配置系统headless属性

因此,如果我们想在Spring引导测试中设置“headless”属性,只需创建一个自定义特定的ContextLoader类扩展SpringBootContextLoader类,并使用将headless属性设置为false覆盖方法
getSpringApplication
,然后为@SpringBootTest分配带有注释@ContextConfiguration的特定ContextLoader。守则:

public class HeadlessSpringBootContextLoader extends SpringBootContextLoader {
    @Override
    protected SpringApplication getSpringApplication() {
        SpringApplication application = super.getSpringApplication();
        application.setHeadless(false);
        return application;
    }
}

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=SpringBootTest.WebEnvironment.NONE)
@ContextConfiguration(loader = HeadlessSpringBootContextLoader.class)
public class ApplicationTests {

    @Test
    public void contextLoads() {

    }

}
也许这对你有帮助。
public class HeadlessSpringBootContextLoader extends SpringBootContextLoader {
    @Override
    protected SpringApplication getSpringApplication() {
        SpringApplication application = super.getSpringApplication();
        application.setHeadless(false);
        return application;
    }
}

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=SpringBootTest.WebEnvironment.NONE)
@ContextConfiguration(loader = HeadlessSpringBootContextLoader.class)
public class ApplicationTests {

    @Test
    public void contextLoads() {

    }

}