Spring H2 Test DB 在每次测试之前不会重置

Posted

技术标签:

【中文标题】Spring H2 Test DB 在每次测试之前不会重置【英文标题】:Spring H2 Test DB does not reset before each test 【发布时间】:2018-12-04 18:45:04 【问题描述】:

编辑:正如 C. Weber 在 cmets 中建议的那样,解决方案是将 @Transactional 添加到测试类中。

我有一些使用 H2 内存数据库的测试。我需要在每次测试之前重置数据库。虽然每次执行测试都会运行我的 SQL 脚本,但数据库没有正确重置,导致删除测试后缺少所需的条目。

测试类:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureTestDatabase(replace=Replace.ANY, connection=EmbeddedDatabaseConnection.H2)
public class RepositoryTests 

    @Autowired
    private Repository repository;

    @Autowired
    private DataSource dataSource;

    @Before
    public void populateDb() 
        Resource initSchema = new ClassPathResource("database/schema.sql");
        Resource initData = new ClassPathResource("database/data.sql");
        DatabasePopulator dbPopulator = new ResourceDatabasePopulator(initSchema, initData);
        DatabasePopulatorUtils.execute(dbPopulator, dataSource);
    

    @Test
    public void testMethod1() 
        // ...
        repository.delete("testdata");
    

    @Test
    public void testMethod2() 
        // ...
        Object test = repository.get("testdata");
        // is null but should be an instance
    

schema.sql 在重新创建它们之前删除所有表。 data.sql 将所有需要的测试数据插入到数据库中。

单独运行testMethod2 成功。但是,运行所有测试会使测试失败并返回 NullPointerException

我已成功尝试使用@DirtiesContext,但这不是一个选项,因为我无法承受每 0.1 秒的测试需要 20 秒的启动时间。

还有其他解决方案吗?

【问题讨论】:

你试过在你的测试类中使用@Transactional吗? 哇,成功了!太感谢了。您应该将此作为解决方案发布:) 完成。我很高兴能为您提供帮助。 【参考方案1】:

Spring Test Framework 提供了一种机制来实现您想要的测试行为。只需使用 @Transactional 注释您的 Test 类即可获得每个测试方法的默认回滚行为。

有一些方法可以配置测试的事务行为,也有一些陷阱(例如在测试方法中使用 RestTemplate),您可以在 Spring 手册的相应章节中阅读更多信息。

Spring Test Framework

【讨论】:

@Transacitonal 注释根本没有帮助我。我将两者放在类级别上,并分别放在方法上,但在脉络中。在我第二次运行测试后,第一次运行测试已经更改了数据库。可能是什么问题?

以上是关于Spring H2 Test DB 在每次测试之前不会重置的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot - h2 DB 测试多次执行脚本

Spring Test Dbunit,H2数据库

未加载 Spring Boot 测试 H2 sql 脚本

用 H2 测试 Spring Boot 数据库的正确方法是啥?

如何在 Spring 中的每次测试之前重新创建数据库?

如何使用Spring Data JPA在H2数据库中保存数据