如何在Spring Boot测试中设置'无头'属性?
问题描述:
我正在使用Spring Boot和JavaFX进行测试(基于解释这个的some excellent YouTube videos)。如何在Spring Boot测试中设置'无头'属性?
,使其与TestFX工作,我需要建立这样的背景下:
@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();
}
我现在要测试的这款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。如何在测试期间设置此属性?
编辑:
更仔细地观察,似乎有2个方面开始,一个春节测试框架开始和一个我在init
方法手动创建,所以测试的应用程序未使用嘲笑豆。如果有人想知道如何获得init()
方法中的测试环境参考,我会非常高兴。
答
Praveen Kumar的评论指出了良好的方向。当我用-Djava.awt.headless=false
运行测试时,则没有例外。
为了解决2个春天上下文的其他问题,我必须做到以下几点:
想这是你的主了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;
}
}
并进行测试,使用这种抽象基类(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。
可能是[link](http://stackoverflow.com/questions/36160353/why-does-swing-think-its-headless-under-spring-boot-but-not-under-spring-or- pl)会帮助你。 –