2016-09-01 2 views
2

Я тестирую использование 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")); 
    } 
} 

Это начинается контекст весны и заменяет «нормальные» бобы мак-бобами, как ожидалось.

Однако, теперь я получаю java.awt.HeadlessException, потому что это свойство «без головы» не установлено как false, как это сделано во время обычного запуска. Как установить это свойство во время теста?

EDIT:

Приглядевшись, кажется, что есть два контекста начала, один, что весна тестирование каркасные начинается и один я создаю вручную в методе init, так что тестируемое приложение не используют издевались бобов , Если кто-то будет иметь представление о том, как получить ссылку на тестовый контекст в методе init(), я был бы очень доволен.

+1

Возможно, это [ссылка] (http://stackoverflow.com/questions/36160353/why-does-swing-think-its-headless-under-spring-boot-but-not-under-spring-or- pl) поможет вам. –

ответ

3

Комментарий от Правеена Кумара указал в хорошем направлении. Когда я запускаю тест с -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"); 
    } 
} 

Это позволяет запустить пользовательский интерфейс с использованием макетных сервисов.

Смежные вопросы