ContextRefreshedEvent запущен слишком рано в тесте интеграции Spring - PullRequest
0 голосов
/ 06 сентября 2018

Я хочу протестировать класс типа Example, который обрабатывает ContextRefreshedEvent и подключается к серверу в методе обработчика:

public class Example {

    @EventListener
    public void onApplicationEvent(ContextRefreshedEvent event) {
        startWebSocketConnection();
    }

    // ...
}

Но в интеграционном тесте контекст приложения создается до запуска и запуска сервера веб-сокетов, поэтому я получаю исключение, говорящее о том, что соединение не установлено (java.net.ConnectException: Connection refused: no further information в данном случае).

Тест выглядит так:

@ExtendWith(SpringExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@SpringBootTest
public class WebSocketDataSourceTest {

    @Autowired 
    private Example example;

    @Autowired
    private WebSocketServer server; // created too late

    // ...
}

Возможно ли как-то подавить ContextRefreshedEvent или отложить создание контекста приложения, чтобы сервер веб-сокетов мог запуститься раньше? Или есть другое решение?

1 Ответ

0 голосов
/ 07 сентября 2018

Кажется, что нет способа подавить событие, вызванное средой Spring, или отложить создание контекста приложения. Поэтому я нашел следующий способ:

import org.springframework.core.env.Environment;

public class Example {

    private boolean skipNextEvent;

    @Autowired
    public Example(Environment environment) {
        skipNextEvent = environment.acceptsProfiles("test");
    }

    @EventListener
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (skipNextEvent) {
            skipNextEvent = false;
            return;
        }
        startWebSocketConnection();
    }

    // ...
}

Тест запускает обработчик событий вручную.

@ExtendWith(SpringExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@SpringBootTest
@ActiveProfiles("test") // set profile "test"
public class WebSocketDataSourceTest {

    @Autowired 
    private Example example;

    @Autowired
    private WebSocketServer server;

    @Test
    public void shouldWork() {
        // ...
        example.onApplicationEvent(null); // trigger manually
        // ...
    }
}
...