【发布时间】:2020-08-08 19:01:26
【问题描述】:
我正在使用 JUnit 5 和 Spring boot 2.2.4 来集成测试我的 Spring Boot 应用程序代码与 MySQL 5.7 数据库,但 strong>以前的测试方法对数据库所做的更改不会回滚,这会导致后面的错误。
我尝试了来自不同 stackoverflow 帖子的答案,例如添加 @Transactional(来自 Spring)、@Rollback(方法和类级别)、@TestExecutionListeners(listeners = {TransactionalTestExecutionListener.class})。我已经单独(以及组合)测试了这些选项,但将它们一起添加到测试代码中。
这是我的测试代码:
@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 是我要测试的类,其中包含创建用户、查找用户、获取所有用户等用例。代码中的其他任何地方都没有特殊配置。
【问题讨论】:
-
好的,请把所有类重命名为正常的命名约定,我看不懂。让Repository调用类实现JPA存储库,不要调用POJO'DAO'和Datasource??我读到这里就得强迫症了。
-
好的。给您带来的不便,我们深表歉意。
-
@JAsgarov 提到的类名没有意义。请将此更改为正确的命名,否则将无法阅读。第二件事,为什么要对您的实际数据库进行集成测试。在类路径中使用 h2,范围为测试或 testRuntimeOnly。在您的资源中定义适当的 application-test.yml。声明测试属性源并使用它。我看到许多注释没有用,因为 DataJpaTest 本身就是您使用的大多数注释的元注释。
-
我已经更新了类名。 @Priyak Dey 最初我使用的是 h2,但我想确保数据库中发生了什么,我能想到的最简单的方法是使用 MySQL,以便我可以连接到它并查看断点处发生的情况。我定义了一个由 spring.profiles.active="test" 激活的附加 application-test.properties。
-
这不是一个解决方案,但我能够让测试用例为我工作。我从 MySQL 切换到 H2,然后在每个测试方法之后回滚。
标签: java spring spring-boot spring-data-jpa integration-testing