現在、単体テストを試みているメソッドがいくつかあります。これらのメソッドは、SpringJdbcTemplatesを使用してDB2v8に対して(実稼働環境で)正常に実行されています。
各SQLは、ステートメントに「WITH UR」を追加することにより、「ダーティリード」を許可します。また、「FETCH FIRST1ROWSONLY」などを追加して「limit」を使用するものもあります。
これは実際のDB2に対しては正常に機能しますが、これらのメソッドをインメモリデータベースに対して単体テストしたいと思います。ここでH2が入ります。
「WITHUR」と「FETCHFIRST..」を削除すればすべて正常に機能しますが、メソッドを変更したくはなく、バックエンドデータベースを変更するだけです。
私が見る限り、構文が異なるため(MODE = DB2を使用していますが)、H2を使用してこれを直接行うことはできません。
さて、何をしますか?別のインメモリデータベースを使用する必要がありますか?メソッドを変更したり、「テスト」機能/ハックを追加したりしたくないので、それはダメです。
アイデアも同様に大歓迎です!
編集
それが私なのか、何なのかはわかりませんが、次のエラーが発生します。Spring3.1とH21.3.166を使用しており、データベースのURLは「jdbc:h2:〜/ testdb; MODE=DB2」であることに注意してください。SQLはH2コンソールで実行しているときに機能しますが、単体テストからは機能しないため、失敗する理由がわかりません(壊れているのはH2ではないと推測します)。
Tests run: 3, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.109 sec <<< FAILURE!
getAdvisor(impl.AdvisorServiceDaoImplTest) Time elapsed: 0.078 sec <<< ERROR!
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT * FROM ADVISOR FETCH FIRST 1 ROWS ONLY ]; nested exception is org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "SELECT * FROM ADVISOR FETCH[*] FIRST 1 ROWS ONLY "; SQL statement:
SELECT * FROM ADVISOR FETCH FIRST 1 ROWS ONLY [42000-166]
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:233)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:603)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:637)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:662)
at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:702)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:178)
at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.queryForObject(NamedParameterJdbcTemplate.java:185)
at impl.AdvisorServiceDaoImpl.getAdvisor(AdvisorServiceDaoImpl.java:150)
at impl.AdvisorServiceDaoImplTest.getAdvisor(AdvisorServiceDaoImplTest.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:62)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:140)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:127)
at org.apache.maven.surefire.Surefire.run(Surefire.java:177)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:338)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:997)
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "SELECT * FROM ADVISOR FETCH[*] FIRST 1 ROWS ONLY "; SQL statement:
SELECT * FROM ADVISOR FETCH FIRST 1 ROWS ONLY [42000-166]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.message.DbException.getSyntaxError(DbException.java:181)
at org.h2.command.Parser.getSyntaxError(Parser.java:484)
at org.h2.command.Parser.prepareCommand(Parser.java:233)
at org.h2.engine.Session.prepareLocal(Session.java:415)
at org.h2.engine.Session.prepareCommand(Session.java:364)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1111)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:71)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:266)
at org.springframework.jdbc.core.PreparedStatementCreatorFactory$PreparedStatementCreatorImpl.createPreparedStatement(PreparedStatementCreatorFactory.java:245)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:581)
... 40 more
編集#2誰かが同じ問題を抱えている場合は、ここで私が見つけたものです。私は以下を使用していました:
<jdbc:embedded-database id="dataSource" type="H2">
<jdbc:script location="classpath:sql/create_schemas.sql"/>
<jdbc:script location="classpath:sql/create_tables.sql"/>
<jdbc:script location="classpath:sql/create_test_data.sql"/>
</jdbc:embedded-database>
これは、Springが汎用Beanを使用してデータソースを再インスタンス化するため、設定が失われたことを意味します。解決策(私の場合)は、次のようにプログラムでデータベースをロードすることでした。
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
EmbeddedDatabase db = builder.setName("salgdb").setType(EmbeddedDatabaseType.H2)
.addScript("sql/create_schemas.sql")
.addScript("sql/create_tables.sql")
.addScript("sql/create_test_data.sql")
.build();