【发布时间】:2018-11-27 16:15:35
【问题描述】:
我正在使用 Spring Boot 框架 (v2.0.2) 构建 REST 服务,其中我在数据库上运行了集成测试。我用谷歌搜索了很多,有很多关于在测试前清理数据库的文章,但不幸的是,我发现它们要么效率低下,要么被黑客入侵,而且不适用于 Spring boot。请您多多包涵并提出解决此问题的好方法吗?
理想情况下,我认为不应该在每次测试之前清除数据库,而是在其中一些测试之前清除数据库,例如套件或每个测试类。找到的建议之一如下所示:
@Autowired
protected Flyway flyway;
@Before
public void init() {
flyway.clean();
flyway.migrate();
}
在每次测试之前重建数据库,显然效率不高。将其更改为静态上下文并使用 @BeforeClass 不起作用,因为 Spring 不注入静态字段。
有没有什么好方法可以从静态上下文中访问这个 flyway bean,以使这个解决方案发挥作用?
这里的子问题: Flyway 有一个命令 clean,它不仅会清除数据,还会删除所有内容,然后 migrate 命令再次执行迁移。这似乎也是开销。由于无论如何都会在启动时检查迁移,因此我认为没有必要在每个测试组之前拆除并重建所有内容。只需清除数据就足够了。您能否就如何实现这一目标提出一些建议?
总而言之,我正在寻找一种在每组集成测试(例如每个类)之前删除数据库数据(如果可能,不是表)的标准方法。我想每个人在使用 Spring boot 时都会面临这个任务,所以也许框架本身考虑了一些不错的解决方案。
谢谢!
【问题讨论】:
-
为什么不在你的测试中使用
@Transactional。这样数据库总是干净的。 -
为什么不使用简单的删除或截断表?您可以选择要删除哪个表?您还可以修复顺序,以便处理外键约束。如果你想玩图书馆,你可以看看 DBUnit。
-
@lealceldeiro 感谢您的建议。可能我不使用事务的主要原因是我想在运行测试组后拥有一个填充的数据库。它对调试有很大帮助,也有助于为客户端应用程序填充数据。另一个原因是我觉得这不是它的目的。在我的业务逻辑中实现事务之后,我最终会遇到嵌套事务,并且可能会遇到许多棘手的问题,因为它的大部分实现都在后台。
-
@gagansingh 如果我能找到一种与 spring 结合的方法,那就太好了。你会在哪里添加这个逻辑?您会使用
@Sql注释并将这些清理脚本放在一个sql 文件中吗?也许将此注释添加到测试类?
标签: java spring-boot junit flyway