Два бина одного типа в тестовом контексте
Существует некоторый базовый контекст для интеграционных тестов:
@ExtendWith (SpringExtension.class)
@SpringBootTest (webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public abstract class BasicContext {……}
BasicContextIT является родительским для интеграционных тестов.
Когда идёт запуск всех тестов, к примеру первым запускается:
public class FirstTestClass extends BasicContext{
@Autowired
private SomeService service;
…….
}
В свою очередь SomeService загружается с некоторыми параметрами в конструкторе:
SomeService(SomeDataAdapter adapter,…)
Итак, для FirstTestClass загружается оригинальный бин - SomeDataAdapter.
Далее, запускается следующий тестовый класс:
public class SecondTestClass extends BasicContext{
@MockBean
private SomeDataAdapter adapter;
@Autowired
private SomeTestedService testedService;
……
И в этом классе у нас есть тесты вида:
@Test
public void someTest(){
testedService.run("……");
verify(adapter,timeout(1000).atLeastOnce()).firstAdapterMethod(any());
verify(adapter,timeout(1000).atLeastOnce()).secondAdapterMethod(any());
}
Но некоторые из них проходят успешно, другие - нет
Как я понял с помощью дебагера, контекст имеет два компонента типа SomeDataAdapter: 1. Оригинальный(обычный) бин из предыдущего тестового класса 2. Мок бина, созданный для этого класса Когда используется оригинальный бин - тест падает, когда макет - проходит
(тест падает, потому что метод в verify у мока не был вызван)
Итак, этот оригинальный бин остался с прошлого теста и соответственно мешает
Это работает, только если поцепить @DirtiesContext над BasicContext. Но это не подходит, потому что контекст будет пересоздаваться для каждого тестового класса. BasicContext является родительским для многих классов, для которых воссозданный контекст не требуется (поэтому повторная сборка контекста для каждого тестового класса делает общий запуск интеграционных тестов очень медленным)
Каким образом можно разрешить данную ситуацию?