Я сделал тест Spring Boot для тестирования потребления JMS.
Тест выглядит следующим образом:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
public class UpdateThingByJmsIntegrationTest {
@Test
@Rollback(false)
public void updateThingByJmsUpdatesDatabase() throws InterruptedException {
final Thing thing = new ThingBuilder().withId(null).build();
final TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
transactionTemplate.execute(transactionStatus -> {
thingRepository.save(thing);
return thing;
});
final String xml = String.format(
"<thingDto><id>%s</id><name>something else</name><location>somewhere</location></thingDto>",
thing.getId());
jmsMessagingTemplate.convertAndSend(thingUpdateQueue, xml);
Thread.sleep(1500L);
final Thing updatedThing = thingRepository.getOne(thing.getId());
assertNotNull(updatedThing);
assertEquals("something else", updatedThing.getName());
assertEquals("somewhere", updatedThing.getLocation());
}
Итак, я сохраняю Thing
в базе данных, затем отправляю сообщение JMS для обновления Thing
.Поскольку потребление JMS происходит в отдельном потоке от самого теста, я жду, а затем пытаюсь убедиться, что Thing
обновлено.
Это прекрасно работает в IntelliJ, но при запуске с Mavenпроисходит сбой из-за того, что поток, использующий сообщение JMS, не может найти Thing
в базе данных.
Я попытался вывести хеш-код объекта (идентификатор) ThingRepository
как в тесте, так и в тесте.код, потребляющий сообщение JMS, и они выходят по-разному.С IntelliJ они одинаковы.Я подозреваю, что это может быть частью проблемы, но я не уверен, как этого избежать.
Я также проверил вывод журнала в IntelliJ против Maven, и я обнаружил, что maven выводит эти строки до начала теста.даже запустить, чего нет у IntelliJ.Не знаю, уместно ли это.
2019-05-13 09:48:53.983 INFO 9271 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2019-05-13 09:48:53.995 INFO 9271 --- [ main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2019-05-13 09:48:53.996 INFO 9271 --- [ main] .SchemaDropperImpl$DelayedDropActionImpl : HHH000477: Starting delayed evictData of schema as part of SessionFactory shut-down'
2019-05-13 09:48:54.000 INFO 9271 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-3 - Shutdown initiated...
2019-05-13 09:48:54.001 INFO 9271 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-3 - Shutdown completed.
Но зачем мне получать другой объект хранилища в тесте и тестируемом классе?
Обновление:
Оказывается, это происходит только при запуске рассматриваемого теста в тот же прогон, что и другой тест.В этом другом тесте у меня есть:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
public class OtherIntegrationTest {
@MockBean
private ThingRepository thingRepository;
Похоже, это «просачивается» в другой мой тест, заставляя контекст использовать макет, в то время как мой тест использует реальную сделку.Есть ли способ избежать этого, или мне нужно найти альтернативу использованию @MockBean?