CommandLineRunners
- это обычные bean-компоненты с одним исключением:
После загрузки контекста приложения Spring boot находит среди всех своих bean-компонентов, которые реализуют этот интерфейс, и автоматически вызывает их метод run
.
Теперь я хотел бы попросить вас сделать следующее:
- Удалите
ContextConfiguration
из теста и поместите точку останова в конструктор MyRunner
. Тест должен выглядеть так:
@RunWith(SpringRunner.class) // if you're on junit 4, adjust for junit 5 if you need
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class MyTest {
@Autowired
private MyRunner myRunner;
@Test
public void testMe() {
System.out.println("hello");
}
}
Запустите тест и убедитесь, что myRunner загружен и его
run
метод называется Теперь смоделируйте этот класс с помощью аннотации MockBean:
@RunWith(SpringRunner.class) // if you're on junit 4, adjust for junit 5 if you need
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
public class MyTest {
@MockBean
private MyRunner myRunner;
@Test
public void testMe() {
System.out.println("hello");
}
}
Запустить тест. Убедитесь, что метод run
не запущен. Контекст вашего приложения теперь должен содержать фиктивную реализацию вашего компонента.
Если вышеприведенное работает, то проблема в аннотациях TestConfig
и ContextConfiguration
. В целом, когда вы запускаете без ContextConfiguration
, вы предоставляете модулю весенней загрузки свободу для mimi c, когда контекст приложения запускается так, как будто это реальное приложение (с автоконфигурациями, разрешением свойств, рекурсивным сканированием bean-компонентов и т. Д.). Однако, если вы установите ContextConfiguration, тест весенней загрузки не будет работать так - он загружает только бины, которые вы указали в этой конфигурации. Нет автоконфигураций, например, не выполняется рекурсивное сканирование bean-компонентов.
Обновление
Основано на комментарии ОП:
Похоже MyRunner
загружается при установке @ContextConfiguration из-за сканирования компонентов. Поскольку у вас есть аннотация @Component
, размещенная в классе MyRunner
, она может быть обнаружена загрузочным движком Spring.
На самом деле здесь существует «опасное» сочетание двух типов определений компонентов: 1. Объекты определяется с помощью @Bean
в @Configuration
аннотации 2. Компоненты, найденные во время сканирования компонентов.
Вот вам вопрос: если вы не хотите имитировать c процесс запуска приложения и вместо этого предпочитаете для загрузки только указанных c бинов, почему вы вообще используете @SpringBootTest
? Может быть, вы можете достичь цели с помощью:
@RunWith(SpringRunner.class)
@ContextConfiguration(YourConfig.class)
public class MyTest {
...
}