我正在测试使用Spring Boot with JavaFX(基于some excellent YouTube videos解释这一点)。
要使其与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上下文并替换" normal"与预期的模拟豆豆。
然而,我现在得到一个java.awt.HeadlessException
,因为这个“无头”'如正常启动时所做的那样,属性不会设置为false。如何在测试期间设置此属性?
编辑:
仔细观察,似乎有2个上下文启动,一个是Spring测试框架启动的,另一个是我在init
方法中手动创建的,因此被测试的应用程序不使用模拟bean。如果有人想知道如何在init()
方法中获得测试上下文引用,我会非常高兴。
答案 0 :(得分:3)
Praveen Kumar的评论指出了良好的方向。当我使用<!DOCTYPE HTML>
<html>
<head>
<!--<link rel="stylesheet"type="text/css" href="newellipse.css">
<script src="jfile/myquery.js"></script>-->
<meta charset="UTF-8">
</head>
<body>
<input id="ipvalue" type="text" value="25x^2+4y^2+100x-40y=-100">
<button onclick="checkFruit()">solve</button>
<p id="demo"></p>
<p id="demo1"></p>
<p id="demo2"></p>
<p id="demo3"></p>
<p id="demo4"></p>
<canvas id="myCanvas"width="578" height="400" style="position:absolute;left:220px;top:50px;"></canvas>
<script>
var canvas = document.querySelector("#myCanvas");
var context2d = canvas.getContext("2d");
var step = 2*Math.PI/1000; // see note 1
var h = 150;
var k = 150;
var r = 80;
context2d.beginPath(); //tell canvas to start a set of lines
for(var theta = 0; theta < 2*Math.PI; theta += step)
{
var x = h + r*Math.cos(theta);
var y = k - 0.5 * r*Math.sin(theta); //note 2.
context2d.lineTo(x,y);
}
context2d.closePath(); //close the end to the start point
context2d.stroke(); //actually draw the accumulated lines
var splitter = /([\-+])?\s*(\d+)?([a-zA-Z])\b/g;
var source = document.querySelector('#ipvalue');
var target = document.querySelector("#demo");
var target1 = document.querySelector("#demo1");
var target2 = document.querySelector("#demo2");
var target3 = document.querySelector("#demo3");
var target4 = document.querySelector("#demo4");
function checkFruit()
{
var equation = splitter.exec(source.value);
console.log('SOURCE: ', source.value);
console.log('EQUATION: ', equation);
console.log('SUGGESTION: ', source.value.match(splitter));
var y = source.value;
switch(y)
{
case "25x^2+4y^2+100x-40y=-100":
var text = "Formula for Ellipse x^2/a^2+y^2/b^2=1";
var text1 = "First RHS side value consider for 1";
var text2 = "LHS side divide by RHS value for 16";
var text3 = "Take a square root of denaminater value";
var text4 = "Find the x and y value";
target.innerHTML = text;
target1.innerHTML = text1;
target2.innerHTML = text2;
target3.innerHTML = text3;
target4.innerHTML = text4;
break;
}
}
</script>
</body>
<html>
运行测试时,没有例外。
要解决2 Spring上下文的另一个问题,我必须执行以下操作:
假设这是您的主要JavaFx启动类:
-Djava.awt.headless=false
对于测试,您使用此抽象基类(jQuery):
@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;
}
}
然后你可以写一个这样的测试:
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();
}
}
这允许使用模拟服务启动UI。
答案 1 :(得分:0)
@SpringBootTest 使用 SpringBootContextLoader 类作为上下文加载器,因此可以通过以下方法从方法SpringBootContextLoader.loadContext
加载ApplicationContext:
SpringApplication application = getSpringApplication();
......
return application.run();
调用方法application.run()
时,应用程序使用其内部无头属性配置系统无头属性。
因此,如果我们想在Spring Boot测试中设置'headless'属性,只需创建一个自定义的特定ContextLoader类扩展SpringBootContextLoader类,并使用set方法覆盖方法getSpringApplication
headless属性为false,然后为特定的ContextLoader分配@SpringBootTest批注@ContextConfiguration。代码:
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() {
}
}