I am using JUnit 5 with Spring boot 2.2.4 for integration testing my Spring Boot application code with MySQL 5.7 database but the changes that a previous test method makes to database aren't rolled back causing errors in the ones that follow.
I've tried answers from different stackoverflow posts such as adding @Transactional
(from Spring), @Rollback
(method as well as class level), @TestExecutionListeners(listeners = {TransactionalTestExecutionListener.class})
. I've tested these options individually (as well as in combination) but adding them in the test code together.
This is my test code:
@DataJpaTest
@Transactional
@Rollback
@ExtendWith(SpringExtension.class)
@Import({UserUsecasesImpl.class})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class UserUsecasesImplINTTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
@Spy
private UserRepository userRepository;
@Autowired
private UserUsecases userUsecases;
@Test
void injectedComponentsAreNotNull(){
assertNotNull(entityManager);
assertNotNull(userRepository);
assertNotNull(userUsecases);
}
@Test
@Rollback
void Create_EntityAlreadyExists_ReturnsException() {
// set up
User expected = UserFixture.user1.toBuilder().build();
// entityManager.persistAndFlush(expected);
userRepository.saveAndFlush(expected);
// execute
User actual = userUsecases.create(expected);
// verify
assertEquals(expected, actual);
verify(userRepository).findOne(any(Example.class));
verify(userRepository, never()).save(any(User.class));
verifyNoMoreInteractions();
}
@Test
void Find_WhenUserPresent_ReturnUser() {
// // set up
User expected = UserFixture.user1.toBuilder().build();
entityManager.persistAndFlush(expected);
// execute
User actual = userRepository.find(expected);
// verify
assertEquals(expected, actual);
}
@Test
// @Transactional
void Find_WhenUserNotPresent_ReturnNull() {
// // set up
User expected = UserFixture.user1.toBuilder().build();
// entityManager.persistAndFlush(UserFixture.user2.toBuilder().build());
// execute
User actual = userUsecases.find(expected);
// verify
assertNull(actual);
}
}
UserUsecasesImpl
is the class that I am trying to test which contains usecases such as creating a user, finding a user, get all users, etc. There is no special configuration anywhere else in the code.
Please implement following fixes and let me know if problem still there:
@Transactional
and @Rollback
. Keep @DataJpaTest
which by default makes all of your tests @Transactional and therefore by default will roll them all back.saveAndFlush
. The flush part is flushing save operation into the database and most likely causes your issue. Use save
instead. More here https://www.baeldung.com/spring-data-jpa-save-saveandflushassertThrows
.In general try not to throw every single annotation you know into the mix at the same time. Add them one at a time as you need them, try to understand what they do.
What is UserUseCases and why does it do most of the logic I would expect the Repository class to do?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.