gpt4 book ai didi

java - 如何在 Spring 中真正单独运行每个集成测试,或者至少在每个测试之前运行所有命令行运行程序?

转载 作者:行者123 更新时间:2023-12-02 11:20:00 25 4
gpt4 key购买 nike

我有一个 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 的某种方法会很好。我不想自己实例化并运行它,这会很麻烦,而且我不确定这在事务方面如何工作。我可以在查询中排除此管理员用户帐户被删除,但我仍然在系统周围进行黑客攻击。

最佳答案

目前,您遇到了先有鸡还是先有蛋的问题,需要存在此管理员帐户并且该管理员帐户存在 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);
}
}

如果您希望测试真正彼此独立,您将需要每次都重新创建上下文并确保每次都删除数据库。这将花费你大量的时间,而且在我看来是不必要的,但如果你有你的理由,你就有你的理由。我个人会 mock 所有的服务。

您可以只使用数据库 JPA Hibernate,就像 spring.jpa.hibernate.ddl-auto= create-drop 一样。我通常不会这样做,只是有一个方法可以清除所有表并在每次测试后运行该方法,但这不是您在问题中所要求的,我希望看到一个 @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) 在您的测试代码中。

关于java - 如何在 Spring 中真正单独运行每个集成测试,或者至少在每个测试之前运行所有命令行运行程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49999633/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com