Как разрешить ленивую ассоциацию в интеграционном тесте, не используя @Transactional? - PullRequest
0 голосов
/ 02 июля 2019

Я провожу некоторые интеграционные тесты со Spring, но пытаюсь упростить свою жизнь, утверждая содержимое некоторых сущностей, которые мне нужно разрешить перед ленивым.

Мой тест похож на:

@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class OrderIT {

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderRepository orderRepository;

    @Test
    public void test01CreateOrder() {

        OrderDto orderDto = createSomeOrderDto();
        orderService.create(orderDto);

        Order order = orderRepository.findByNumber("123456");
        // order asserts ...
    }

}

После этого у нас есть тесты в том же классе, которые используют этот порядок (тесты, такие как изменение порядка и т. Д.).Вот почему я не использую @Transactional в тестовом методе, а интеграционные тесты выполняются с учетом имени заказа, потому что я использую предыдущий тест в качестве основы для следующего теста.

Это работает очень хорошо.Но моя проблема в том, когда мне нужно улучшить свои утверждения, пытаясь разрешить некоторую ленивую информацию о сущности.

Я не могу просто, например, сделать order.getReponsable() в моем тесте, потому что я получу ошибку LazyException.

Что работает (но мне это не нравится)

Единственный способ, который я нашел для этого в тестах, - это создать специальный запрос к хранилищу, извлекающий этот responsable.Я могу назвать этот запрос, и ленивая ассоциация больше не будет проблемой.Но я не хотел бы создавать методы репозитория только для целей тестирования.

То, что я пытался (и не смог)

Моя идея заключалась в том, чтобы ввести TestEntityManager в моем интеграционном тесте с @AutoConfigureTestEntityManager натестовый класс, в надежде получить доступ к getEntityManager и, наконец, создать запрос на тест, например:

Order order = (Order) testEntityManager.getEntityManager().createQuery("SELECT o FROM Order o JOIN FETCH o.responsable WHERE o.number = " + "123456").getSingleResult();

Будет идеально, если сработает.Но EntityManager недоступен:

> java.lang.IllegalStateException: No transactional EntityManager found

Есть другая альтернатива?Опять же, @Transactional в методе тестирования для меня не вариант.

1 Ответ

0 голосов
/ 02 июля 2019

Я только что нашел альтернативу.Я не знаю, предлагает ли Spring что-то лучше, но сработало.

Я просто вставил EntityManagerFactory в свой класс интеграционных тестов:

@Autowired
private EntityManagerFactory entityManagerFactory;

И сделал свой запрос, используя менеджер сущностей, но я создал один:

Order order = (Order) entityManagerFactory.createEntityManager().createQuery("SELECT o FROM Order o JOIN FETCH o.responsable WHERE o.number = " + "123456").getSingleResult();
...