Skip to content
Advertisement

How to make an integration test with one transaction for all database calls and rollback it afterwards?

I’m, writing an integration test, annotated with @SpringBootTest.

Suppose I create some product using pure SQL from my test, call calculation service that do some calculations based on it, and it calls another service to save those calculation results in different tables.

What I need is to rollback all the changes made after test is finished.

I read different questions, tried to use @Transactional on class or test-method.

Tried to put database property autocommit=false.

Tried to make SqlSession object and Spy it in @Before into service that saves data into different tables and rollback it in @After. Also, tried to use Connection with autocommit=false but it won’t work, it’s all different transactions anyway.

The @Repository beans are also annotated with @Mapper because we use My-Batis. It seems my-batis creates new transaction whenever it’s mapper is called.

So the only idea I have left is to initiate in-memory database for integration tests and use it. Or probably I am missing some things and it could be done in other way just trough the transactions management?

How do I do all the calls in one transaction so they see the changes made and rollback it afterwards?

Here is an example code of a test I am trying to do:

JavaScript

Advertisement

Answer

After some time, I found solution to this problem. It is not sofisticated and beatifull, I’d say it’s a bit ugly but it works.

Mybatis’s SqlSession has a method getMapper, using it you can get a mapper that sees the changes done in your current transaction, it looks like this:

JavaScript

So I got all the mappers I need and injected them into beans using ReflectionTestUtils.setField.

SqlSession itself was rolled back in @After annotated method.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement