@Transactional annotation in Spring Test

It means that your server won’t rollback your changes because it will run in another environment than the test environment. Only changes you have made in your test environment would be rollbacked.

For instance:

@Autowired
private AnyRepository anyRepository;

@Test
@Transactional
void testSave(){
  anyRepository.save(new AnyEntity());
  // Will create an entity from your test environment
}

@Test
@Transactional
void testRead(){
  anyRepository.findAll();
  // Won't find any entities since they were rollbacked
}

On the contrary, if you launched a local instance of Spring using @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT) for instance), it is detached from your unit test environment, hence:

@Autowired
MockMvc mvc;

@Test
@Transactional
void testSave(){
  mvc.perform(post(/* enough to create an entity */);
  // Your server, detached from test environment, persists the entity
}

@Test
@Transactional
void testRead(){
  mvc.perform(get(/* enough to get that entity */);
  // Will get previously created entity (if testSave was run before)
}

If you want to rollback after sending a web request, you could use the @DirtiesContext annotation to reset your context, or check Reset database after each test on Spring without using DirtiesContext.

edit: following comments on original post, it was not clear whether you needed to use WebEnvironment.RANDOM_PORT or if it was a simple question.
Most likely, if you do not need WebEnvironment.RANDOM_PORT, you can simply use WebEnvironment.MOCK, which runs in the same environment that the JUnit tests, hence would actually rollback.

CLICK HERE to find out more related problems solutions.

Leave a Comment

Your email address will not be published.

Scroll to Top