Тест Spring Boot не работает в Maven, работает в IntelliJ

Я сделал тест 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?

Как у вас с тестом Maven? Как отдельный тест mvn test -Dtest= или как часть сборки с другими тестами? Может быть, это изоляция между тестами, которая терпит неудачу?

Karol Dowbecki 13.05.2019 13:43

Я запускаю чистую установку mvn. Я попробую запустить его как одиночный тест.

Tobb 13.05.2019 14:29

@KarolDowbecki Это работает, если я запускаю его как один тест через maven. Я также вижу, что в этом сценарии я получаю один и тот же хэш-код объекта в тесте и тестируемом классе. Все тесты, которые выполняются как тесты загрузки Spring, аннотируются DirtiesContext BEFORE_EACH_METHOD.

Tobb 13.05.2019 14:32

Я попытался запустить его вместе с другим тестовым классом без неудачных тестов, и он работает. Затем я попробовал вместе с другим тестовым классом, у которого есть неудачный тест, и он не работает. Так что может показаться, что ошибка вызвана другим тестом, я проверю это немного подробнее.

Tobb 13.05.2019 14:34

Запуск одиночных тестов был хорошим советом, спасибо :)

Tobb 13.05.2019 14:35

Как здесь «выполнение одиночных тестов» является допустимым и принятым ответом?

GabrielOshiro 03.03.2022 20:35

@GabrielOshiro Это помогло мне решить мою проблему, и я не вижу других ответов, так что.

Tobb 03.03.2022 20:37

@Tobb, хе-хе-хе, я вижу, хорошо, если у вас когда-нибудь будет больше информации, и вы можете добавить свой собственный ответ, который был бы очень полезен и ценен. Спасибо

GabrielOshiro 03.03.2022 22:02

@Tobb Большое спасибо

GabrielOshiro 14.03.2022 23:02
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
5
9
1 388
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это может быть вызвано отсутствием надлежащей изоляции тестов. Если тест updateThingByJmsUpdatesDatabase работает сам по себе и дает сбой при запуске как часть набора тестов во время сборки, например. когда тесты запускаются с mvn clean install.

Вы должны проверить это с помощью запуск этого единственного теста, используя Maven:

mvn test -Dtest=ClassName.updateThingByJmsUpdatesDatabase

Я обновлю свой вопрос результатами одного теста.

Tobb 13.05.2019 14:45

Быстрое решение — добавить @DirtiesContext к тесту, в котором используется @MockBean. Надлежащее исправление может быть предоставлено только в том случае, если вы покажете полное определение контекста теста для обоих тестов, например. применяемые аннотации и способ выполнения теста. На данный момент недостаточно информации.

Karol Dowbecki 13.05.2019 14:48

Все мои тесты уже есть @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)..

Tobb 13.05.2019 15:06

Добавлены определения классов к моему вопросу

Tobb 13.05.2019 15:08

Вам нужно AFTER_EACH_TEST_METHOD, так как оно переходит к следующему тесту, если только следующий тест не помечен DirtiesContext. Пожалуйста, опубликуйте пример, чтобы воспроизвести проблему, в настоящее время вы предоставили только часть необходимой информации.

Karol Dowbecki 13.05.2019 15:11

Все мои тесты имели грязный контекст и перед каждым тестовым методом. Изменение его на после каждого метода тестирования, кажется, помогает :) не уверен, почему, но кажется, что они должны привести к тому же самому. Хотя имеет смысл иметь After, давайте тесты уберут за собой.

Tobb 13.05.2019 15:40

@Tobb в качестве примечания: @DirtiesContext действительно является хаком, который увеличивает время выполнения набора тестов, поскольку контекст не используется повторно.

Karol Dowbecki 13.05.2019 15:52

Да, я действительно хочу начать со свежего ActiveMQ и базы данных для каждого теста. Сами бобы не меняются от теста к тесту. Знаете ли вы, есть ли способ просто очистить внешние ресурсы, но сохранить сам контекст весны?

Tobb 13.05.2019 16:04

Другие вопросы по теме