繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM