![](/img/trans.png)
[英]How to run some code before each JUnit @Test method individually, without using @RunWith nor AOP?
[英]How to run each integration test truly individually in Spring, or at the very least run all commandlinerunners before each test?
我有一个Spring Boot应用程序,正在使用spring-boot-starter-test。
我有一堆集成测试,这些测试使用REST调用将数据插入到应用程序中。 我用@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
运行它们
每次测试后,我都会在数据库中得到一些数据。 我希望每个测试都是真正独立的,但是我还没有找到一种方法。 我尝试将@Rollback放在每个测试中,但是由于我是通过REST调用从外部插入数据,因此可以理解这是行不通的。
因此,以前我只是通过执行删除查询(即类似Query deleteProjects = entityManager.createQuery("DELETE FROM Project"); deleteProjects.executeUpdate();
类的方法,以相当低级的方式来删除测试之间的所有数据Query deleteProjects = entityManager.createQuery("DELETE FROM Project"); deleteProjects.executeUpdate();
在测试后为每个实体。
但是,我最近添加了将在CommandLineRunner中创建的管理员用户帐户。 我发现此CommandLineRunner对于所有组合的测试也仅运行一次,因此在第一个测试完成并且删除了所有数据之后,我失去了管理员角色。
什么是设置此内容的好方法? 我意识到启动整个应用程序需要花费一些时间,因此全新的启动将不是理想的选择。 告诉Spring在每次测试之前运行CommandLineRunner的一种方法会很好。 我不想自己实例化并运行它,那会很麻烦,而且我不确定这在交易方面如何工作。 我可以从查询中删除该管理员用户帐户,但是我仍然在整个系统中乱砍。
当前,您有一个麻烦的问题,那就是需要拥有该管理员帐户,而该管理员帐户必须具有Spring上下文。 我发现执行此操作的一个好方法是拥有一个Spring Profile @Profile("test")
并将其放在创建该管理员帐户所需的某个Component
上:
@Component
@Profile("test")
public class CreateAdminBean {
@Autowired
UserRepo repo;
public CreateAdminBean() {
// TODO your job but something like:
User admin = new User();
admin.setAdmin(true);
repo.create(admin);
}
}
如果要使测试真正彼此独立,则需要每次都重新创建上下文,并确保每次擦除数据库。 这将花费您时间,而IMO是不必要的,但是如果您有自己的理由,则有自己的理由。 我个人会嘲笑所有服务。
您只需将数据库JPA Hibernate设置为spring.jpa.hibernate.ddl-auto= create-drop
。 我通常不这样做,只是有一个清除所有表并在每次测试后运行的方法,但这不是您在问题中要问的,我希望看到一个@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
在您的测试代码中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.