我正在为Grails(V3.2.3)应用程序创建功能测试。在测试期间,它在h2数据库上运行。测试调用其余的API。因为应用程序需要支持几个互斥的数据集,我试图在每次测试之前加载数据并在每次测试后清理它。但是,这会产生非常不一致的结果。有时它抛出其他时候工作正常
org.hibernate.ObjectNotFoundException:没有给定的行 标识符存在。
但是,如果我使用 localhost:{port} / dbconsole 检查数据库,那么数据就在那里。什么是错误的想法以及如何解决它?
通过创建域对象然后在它们上调用.save(flush:true)来加载数据。 这是在Spock的设置方法中完成的。
通过在Spock的清理方法中调用数据来清除数据:
static void clearAllData() {
Session session = Holders.applicationContext.getBean(SessionFactory).currentSession
session.createSQLQuery("SET REFERENTIAL_INTEGRITY FALSE").executeUpdate()
getH2TruncateScript().each {
try {
session.createSQLQuery(it).executeUpdate()
} catch(GenericJDBCException e) {
//ignore CANNOT TRUNCATE xxx, as several domain classes are backed by views
}
}
session.createSQLQuery("SET REFERENTIAL_INTEGRITY TRUE").executeUpdate()
session.clear()
}
测试类注释为: @积分 @Rollback @ SLF4J
application.groovy中的h2数据库设置如下:
environments {
test {
dataSource {
driverClassName = 'org.h2.Driver'
url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;INIT=RUNSCRIPT FROM '../db/h2_init.sql'"
username = 'sa'
password = ''
dbCreate = 'create-drop' //also tried 'create' and 'update'
logSql = true
formatSql = true
}
}
}
在启动期间加载一次时效果很好。
class BootStrap {
def init = { servletContext ->
if (Environment.current == Environment.TEST) {
..load data here
}
}
}
但是,这不是一个选项,因为测试是为了验证对新旧数据格式的支持。这些格式是互斥的。