我使用Play 2.3和Hibernate。 在第一次启动应用程序时,我希望将一些数据作为默认值插入到数据库中。
在我的情况下,我有一个实体课" Studycourse"。所有表都是在首次运行时通过JPA创建的。
我使用DB evolution(1.sql)来插入默认数据,例如:
INSERT INTO studycourse (id, title) VALUES (1, 'Computer Science');
这在使用普通"激活器运行"命令。但如果我做了#34;激活测试"并使用inMemoryDatabase()开始一个简单的集成测试,我得到以下错误:
[error] play - Table "STUDYCOURSE" not found; SQL statement: INSERT INTO studycourse (id, title) VALUES (1, 'Computer Science')
我想,初始JPA设置不是在内存数据库中完成的。
问题:有关于如何做到这一点的最佳做法吗?
集成测试如下:
public class IntegrationTest {
@Test
public void test() {
running(testServer(3333, fakeApplication(inMemoryDatabase())), HTMLUNIT, new Callback<TestBrowser>() {
public void invoke(TestBrowser browser) {
browser.goTo("http://localhost:3333");
assertThat(browser.pageSource()).contains("Your new application is ready.");
}
});
}
}
提前致谢。
答案 0 :(得分:0)
你原来的问题实际上是在询问&#34;我如何在测试环境中执行我的JPA初始化步骤,以便在运行涉及我的数据库的集成测试时填充我的内存数据库?&#34;。
我的回答不会直接解决这个问题,但会总结我们如何解决您尝试解决的相同潜在问题。
我对你的目标的解释是你想:
数据库架构迁移
正如我在上面的评论中提到的,我们使用http://flywaydb.org进行数据库架构迁移,它一直是一个出色的工具。 Flyway有一个SBT插件,因此您可以从flywayClean
直接运行flywayMigrate
和activator
来立即删除并重新初始化您的数据库。
Flyway支持复杂的文件名版本,因此您可以执行v1.1.0.sql
,v1.1.1.sql
和v1.2.0.sql
等SQL脚本。如果您尝试执行的迁移脚本不是对数据库现有状态的纯粹改进,那么Flyway也会抱怨。这意味着我们正在使用flyway将数据库模式迁移推向生产,如果我们做了一些愚蠢的事情,我们相信这会失败。当然,为了安全起见,我们总是在迁移之前进行数据库备份。
最后,如果你想使用服务方法而不仅仅是原始SQL,Flyway甚至会让你执行java程序来填充数据库。
无论如何,你在这里的选择基本上是Play evolutions,Flyway或Liquibase。
内存数据库与开发数据库
在这个问题上,我看到了两个主要职位:
永远不要在内存数据库上进行测试,因为那样你的测试就不会出现 揭示内存数据库和内存数据库之间的微妙差异 您的生产数据库,或
使用内存数据库进行本地测试,但至少要有你的 构建服务器使用开发数据库。
例如,您可以在http://blog.jooq.org/2014/06/26/stop-unit-testing-database-code/结尾处看到评论。
选项#1总体上提供了更高的速度,但延迟了编写错误代码和进行失败的集成测试之间的反馈时间。
选项#2总体上会略微降低速度,但会为您提供有关真实数据库的即时反馈。
与工程中的大多数事情一样,没有最好的&#34;解决方案,只是一组对您的团队最有意义的权衡。
选择ORM图层
我们最初从Hibernate开始,但最终切换到http://jooq.org。有关jOOQ积极概述,请参阅http://www.vertabelo.com/blog/technical-articles/jooq-a-really-nice-alternative-to-hibernate;有关这两者的详细讨论,请参见http://blog.jooq.org/2012/04/21/jooq-and-hibernate-a-discussion/。
Hibernate似乎对我们很有吸引力,因为它非常成熟且非常流行,但是当我们开始遇到经典的SQL与面向对象的阻抗不匹配(如如何处理继承)时,Hibernate需要学习曲线和一些设置开销。
我们推断,如果我们要承担这种开销,为什么不直接使用SQL来进行映射呢?因此,我们切换到JOOQ并且能够编写一些非常干净,优雅且可测试的代码。如果你在休眠路径上走得太远,我建议你去看看jOOQ。
如果您已经深入了解Hibernate并且它对您有用,那么转换可能没什么价值。
数据库集成测试的最佳实践
我想知道这个确切的问题并在https://groups.google.com/forum/#!topic/jooq-user/GkBW5ZGdgwQ发布了这个问题。 jOOQ的作者Lukas回应了一些一般性的评论。
此时,我们对大多数DAO和服务类进行了集成测试。我们的测试是在flywayClean
和flywayMigrate
运行后运行的。然后,编写每个测试以进行清理。最大的问题是性能,到目前为止这不是一个问题,但可能会在以后出现问题。
我也发布了这个并收到了一个有用的答案。请参阅https://groups.google.com/d/msg/play-framework/BgOCIgz_9q0/jBy8zxejPEkJ。
免责声明:我们即将启动我们的应用程序,但尚未在生产环境中运行,因此其他人可能还有其他最佳实践要添加。