Я сделал тест 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 vs 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?
Я запускаю чистую установку mvn. Я попробую запустить его как одиночный тест.
@KarolDowbecki Это работает, если я запускаю его как один тест через maven. Я также вижу, что в этом сценарии я получаю один и тот же хэш-код объекта в тесте и тестируемом классе. Все тесты, которые выполняются как тесты загрузки Spring, аннотируются DirtiesContext BEFORE_EACH_METHOD.
Я попытался запустить его вместе с другим тестовым классом без неудачных тестов, и он работает. Затем я попробовал вместе с другим тестовым классом, у которого есть неудачный тест, и он не работает. Так что может показаться, что ошибка вызвана другим тестом, я проверю это немного подробнее.
Запуск одиночных тестов был хорошим советом, спасибо :)
Как здесь «выполнение одиночных тестов» является допустимым и принятым ответом?
@GabrielOshiro Это помогло мне решить мою проблему, и я не вижу других ответов, так что.
@Tobb, хе-хе-хе, я вижу, хорошо, если у вас когда-нибудь будет больше информации, и вы можете добавить свой собственный ответ, который был бы очень полезен и ценен. Спасибо
@Tobb Большое спасибо




Это может быть вызвано отсутствием надлежащей изоляции тестов. Если тест updateThingByJmsUpdatesDatabase работает сам по себе и дает сбой при запуске как часть набора тестов во время сборки, например. когда тесты запускаются с mvn clean install.
Вы должны проверить это с помощью запуск этого единственного теста, используя Maven:
mvn test -Dtest=ClassName.updateThingByJmsUpdatesDatabase
Я обновлю свой вопрос результатами одного теста.
Быстрое решение — добавить @DirtiesContext к тесту, в котором используется @MockBean. Надлежащее исправление может быть предоставлено только в том случае, если вы покажете полное определение контекста теста для обоих тестов, например. применяемые аннотации и способ выполнения теста. На данный момент недостаточно информации.
Все мои тесты уже есть @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)..
Добавлены определения классов к моему вопросу
Вам нужно AFTER_EACH_TEST_METHOD, так как оно переходит к следующему тесту, если только следующий тест не помечен DirtiesContext. Пожалуйста, опубликуйте пример, чтобы воспроизвести проблему, в настоящее время вы предоставили только часть необходимой информации.
Все мои тесты имели грязный контекст и перед каждым тестовым методом. Изменение его на после каждого метода тестирования, кажется, помогает :) не уверен, почему, но кажется, что они должны привести к тому же самому. Хотя имеет смысл иметь After, давайте тесты уберут за собой.
@Tobb в качестве примечания: @DirtiesContext действительно является хаком, который увеличивает время выполнения набора тестов, поскольку контекст не используется повторно.
Да, я действительно хочу начать со свежего ActiveMQ и базы данных для каждого теста. Сами бобы не меняются от теста к тесту. Знаете ли вы, есть ли способ просто очистить внешние ресурсы, но сохранить сам контекст весны?
Как у вас с тестом Maven? Как отдельный тест
mvn test -Dtest=или как часть сборки с другими тестами? Может быть, это изоляция между тестами, которая терпит неудачу?