首页 > 解决方案 > 如何在不使用 @Transactional 的集成测试中解决惰性关联?

问题描述

我正在使用 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()对我的测试进行 a,因为我会收到一个LazyException错误。

什么有效(但我不喜欢它)

我发现在测试中这样做的唯一方法是在存储库上创建一个特定的查询来获取 this 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测试方法对我来说不是一个选项。

标签: springjpaspring-data-jpaintegration-testinglazy-loading

解决方案


我刚刚找到了一个替代方案。我不知道春天是否提供更好的,但工作。

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();

推荐阅读