【发布时间】:2018-07-26 11:07:37
【问题描述】:
我正在为一些数据访问代码编写单元测试。设置中的关键部分包括:
-
jOOQ为 CRUD 操作生成的工件 -
Liquibase处理架构演变
考虑到这么多,我正在尝试按如下方式设置测试:
创建一个
java.sql.Connection以使用适当命名的架构初始化 H2 数据库。 (值得注意的是,连接是使用以下 URL 创建的:jdbc:h2:mem:[schema-name];MODE=MySQL;DB_CLOSE_DELAY=-1)。使用上述连接,调用
Liquibase以运行更改日志,该日志创建数据库架构中的所有对象使用上述连接,创建一个
org.jooq.DSLContext,用于测试数据访问组件。
一个抽象类将这三个步骤封装在一个@Before 注释方法中,并且测试类扩展这个抽象类以利用初始化的org.jooq.DSLContext 实例。像这样:
abstract class DbTestBase {
protected lateinit var dslContext: DSLContext
private lateinit var connection: Connection
open fun setUp() {
connection = DriverManager.getConnection("jdbc:h2:mem:foo;MODE=MySQL;DB_CLOSE_DELAY=-1")
// invoke Liquibase with this connection instance...
dslContext = DSL.using(connection, SQLDialect.H2)
}
open fun tearDown() {
dslContext.close()
connection.close()
}
}
class MyTest : DbTestBase() {
private lateinit var repository: Repository
@Before override fun setUp() {
super.setUp()
repository = Repository(dslContext)
}
@After override fun tearDown() {
super.tearDown()
}
@Test fun something() {
repository.add(Bar())
}
}
这会导致以下异常:
Caused by: org.h2.jdbc.JdbcSQLException: Schema "foo" not found; SQL statement:
insert into `foo`.`bar` (`id`) values (?) [90079-196]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.command.Parser.getSchema(Parser.java:688)
at org.h2.command.Parser.getSchema(Parser.java:694)
at org.h2.command.Parser.readTableOrView(Parser.java:5535)
at org.h2.command.Parser.readTableOrView(Parser.java:5529)
at org.h2.command.Parser.parseInsert(Parser.java:1062)
at org.h2.command.Parser.parsePrepared(Parser.java:417)
at org.h2.command.Parser.parse(Parser.java:321)
at org.h2.command.Parser.parse(Parser.java:293)
at org.h2.command.Parser.prepareCommand(Parser.java:258)
at org.h2.engine.Session.prepareLocal(Session.java:578)
at org.h2.engine.Session.prepareCommand(Session.java:519)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1204)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:73)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:288)
at org.jooq.impl.ProviderEnabledConnection.prepareStatement(ProviderEnabledConnection.java:106)
at org.jooq.impl.SettingsEnabledConnection.prepareStatement(SettingsEnabledConnection.java:70)
at org.jooq.impl.AbstractQuery.prepare(AbstractQuery.java:410)
at org.jooq.impl.AbstractDMLQuery.prepare(AbstractDMLQuery.java:342)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:316)
... 25 more
我可以在重新生成架构的位置看到 Liquibase 日志记录。并且我已经更改了 H2 URL 以创建基于文件的数据库,我能够检查并验证架构确实存在。
如果能帮助我发现方法中的任何错误,我将不胜感激。
【问题讨论】:
-
也许将
INIT=create schema if not exists foo添加到您的连接字符串中,如下所示:"jdbc:h2:mem:foo;INIT=create schema if not exists foo\;MODE=MySQL;DB_CLOSE_DELAY=-1" -
hmmm 但这不会创建一个空的数据库/模式吗?我需要使用
Liquibase生成的架构版本,以便jOOQ生成的代码能够工作。 -
什么是“Liquibase”生成的架构版本?
-
@hsl 你是对的。再次阅读您的问题。可能是 jOOQ 中的一个问题,我对此一无所知。
-
@LukasEder 也许我之前的评论措辞不佳。我的意思是,在这个过程中,
Liquibase从更改日志中重新创建数据库/模式(这是模式中所有对象的一种清单)。重新创建该数据库/模式后,我想使用我的jOOQ生成的代码与之交互。
标签: java sql h2 liquibase jooq