【问题标题】:Support DB2 functions in H2 database while unit testing在单元测试时支持 H2 数据库中的 DB2 功能
【发布时间】:2015-08-20 08:12:25
【问题描述】:

我们有一个 DB2 数据库在生产中,我们正在设置一个 H2 内存数据库用于测试。我知道即使我们在 DB2 模式下配置 H2,也不是所有的 DB2 功能都受支持。 我们如何对包含数据库特定功能但在 H2 中尚不支持的 SQL 进行单元测试?

如果我们开始编写 H2 特定的 DB 服务,那么我们将结束编写不同层的功能代码。

功能不支持

VARCHAR_FORMAT

H2 配置

jdbc:h2:mem:test;MODE=DB2

H2版

1.4.188

Java 堆栈跟踪

Caused by: org.h2.jdbc.JdbcSQLException: Function "VARCHAR_FORMAT" not found; SQL statement:
select S.SCHEDULE_ID scheduleId, VARCHAR_FORMAT(S.START_DATE, 'DD-Mon-YYYY') startDate
from ScheduleSubscription S WITH UR  [90022-182]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.message.DbException.get(DbException.java:179) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.message.DbException.get(DbException.java:155) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.readJavaFunction(Parser.java:2333) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.readFunction(Parser.java:2385) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.readTerm(Parser.java:2719) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.readFactor(Parser.java:2251) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.readSum(Parser.java:2238) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.readConcat(Parser.java:2208) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.readCondition(Parser.java:2058) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.readAnd(Parser.java:2030) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.readExpression(Parser.java:2022) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.parseSelectSimpleSelectPart(Parser.java:1934) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.parseSelectSimple(Parser.java:1966) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.parseSelectSub(Parser.java:1860) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.parseSelectUnion(Parser.java:1681) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.parseSelect(Parser.java:1669) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.parsePrepared(Parser.java:433) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.parse(Parser.java:305) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.parse(Parser.java:277) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.command.Parser.prepareCommand(Parser.java:242) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.engine.Session.prepareLocal(Session.java:446) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.engine.Session.prepareCommand(Session.java:388) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1190) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:72) ~[h2-1.4.182.jar:1.4.182]
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:666) ~[h2-1.4.182.jar:1.4.182]
    at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:295) ~[commons-dbcp-1.4.jar:1.4]
    at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:318) ~[commons-dbcp-1.4.jar:1.4]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_35]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_35]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_35]
    at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_35]
    at org.apache.ibatis.logging.jdbc.ConnectionLogger.invoke(ConnectionLogger.java:54) ~[mybatis-3.2.8.jar:3.2.8]
    at $Proxy35.prepareStatement(Unknown Source) ~[na:na]
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.instantiateStatement(PreparedStatementHandler.java:73) ~[mybatis-3.2.8.jar:3.2.8]
    at org.apache.ibatis.executor.statement.BaseStatementHandler.prepare(BaseStatementHandler.java:85) ~[mybatis-3.2.8.jar:3.2.8]
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.prepare(RoutingStatementHandler.java:57) ~[mybatis-3.2.8.jar:3.2.8]
    at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:73) ~[mybatis-3.2.8.jar:3.2.8]
    at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:59) ~[mybatis-3.2.8.jar:3.2.8]
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:267) ~[mybatis-3.2.8.jar:3.2.8]
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:137) ~[mybatis-3.2.8.jar:3.2.8]
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:96) ~[mybatis-3.2.8.jar:3.2.8]
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:77) ~[mybatis-3.2.8.jar:3.2.8]
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:108) ~[mybatis-3.2.8.jar:3.2.8]
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:102) ~[mybatis-3.2.8.jar:3.2.8]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_35]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[na:1.6.0_35]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_35]
    at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_35]
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:358) ~[mybatis-spring-1.2.2.jar:1.2.2]
    ... 47 common frames omitted

【问题讨论】:

  • 另一个很好的例子说明为什么在测试和生产中使用不同的 DBMS 是一个坏主意。

标签: java database unit-testing db2 h2


【解决方案1】:

创建一个名为 VARCHAR_FORMAT 的 H2 函数,并确保它至少为测试数据返回正确的值。

这当然需要为 H2 中尚不存在的每个功能付出努力,但非常可行。测试也保持干净。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-02-12
  • 2019-04-01
  • 2017-12-30
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多