[英]Spring Data JPA database changes after each method don't roll back in integration tests
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 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})
.我尝试了来自不同 stackoverflow 帖子的答案,例如添加@Transactional
(来自 Spring)、@Rollback(方法以及@Rollback
级别)、 @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. UserUsecasesImpl
是我正在尝试测试的 class ,它包含创建用户、查找用户、获取所有用户等用例。代码中的其他任何地方都没有特殊配置。
Please implement following fixes and let me know if problem still there:请实施以下修复,如果问题仍然存在,请告诉我:
@Transactional
and @Rollback
.删除所有@Transactional
和@Rollback
。 Keep @DataJpaTest
which by default makes all of your tests @Transactional and therefore by default will roll them all back.保留@DataJpaTest
,默认情况下使您的所有测试 @Transactional ,因此默认情况下会将它们全部回滚。saveAndFlush
.不要使用saveAndFlush
。 The flush part is flushing save operation into the database and most likely causes your issue.刷新部分是将保存操作刷新到数据库中,很可能会导致您的问题。 Use save
instead.改用save
。 More here https://www.baeldung.com/spring-data-jpa-save-saveandflush更多在这里https://www.baeldung.com/spring-data-jpa-save-saveandflushassertThrows
.如果您期待异常,请使用assertThrows
对其进行断言。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?什么是 UserUseCases,为什么它会执行我希望存储库 class 执行的大部分逻辑?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.