mardi 2 juillet 2019

How to resolve a lazy association on a integration test not using the @Transactional?

I'm doing some integration tests with Spring but I'm trying to simplify my life when asserting the content of some entities that I need to resolve a lazy before.

My test is like:

@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 ...
    }

}

After that we have tests on the same class that use this order (tests like changing the order, etc). This is why I'm not using @Transactional on the test method and the integration tests are executed respecting the order name, because I use the previous test as base for the next test.

This works very good. But my problem is when I need to improve my asserts trying to resolve some lazy information of the entity.

I can't just, per example, do a order.getReponsable() on my test because I will receive a LazyException error.

What works (but I don't like it)

The only way I found to do that on tests is creating a specific query on the repository fetching this responsable. I can call this query and the lazy association will no be a problem anymore. But I would not like to create repository methods just for testing purposes.

What I tried (and failed)

My idea was inject the TestEntityManager on my integration test with @AutoConfigureTestEntityManager on the test class, on the hope to access the getEntityManager and, finally, create a query on the test, like this:

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

Will be perfect if worked. But the EntityManager is not available:

> java.lang.IllegalStateException: No transactional EntityManager found

There is another alternative? Again, the @Transactional on the test method is not an option for me.

Aucun commentaire:

Enregistrer un commentaire