我有一个Spring Boot应用程序,我正在使用spring-boot-starter-test。
我有一堆集成测试,使用REST调用将数据插入应用程序。我用@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
每次测试后,我都会在数据库中找到一些数据。我希望每个测试都是真正独立的,但我还没有找到一种方法。我尝试在每个测试中放置@Rollback,但由于我通过REST调用从外部插入数据,这可以理解为不起作用。
所以以前我只是通过在运行测试后为每个实体执行删除查询(即类似Query deleteProjects = entityManager.createQuery("DELETE FROM Project"); deleteProjects.executeUpdate();
)来删除测试之间的所有数据,而是以相当低级的方式删除。
但是,我最近添加了一个将在CommandLineRunner中创建的管理员用户帐户。我发现这个CommandLineRunner也只为所有测试组合运行一次,所以在第一次测试完成并删除所有数据后,我将失去管理员角色。
设置它的好方法是什么?我意识到启动整个应用程序需要一些时间,所以一个完整的新启动不会是理想的。在每次测试之前告诉Spring运行CommandLineRunner的一些方法会很好。我不想自己实例化和运行它,这将非常hacky,我不确定这在交易方面如何工作。我可以排除此管理员用户帐户在查询中被删除,但之后我仍在浏览系统。
答案 0 :(得分:1)
目前,您需要拥有此管理员帐户以及此管理员帐户的Spring上下文存在鸡和蛋问题。我发现这样做的一个好方法是拥有一个Spring配置文件@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)
代码。