2017-07-17 68 views
1

JPAレイヤとデータベースとの間で統合テストを作成して、書いたSQLが正しいことを確認しています。実際のデータベースはOracleですが、残念なことに、私のテストのデータベースがDerbyでなければならないという理由から自然にいくつかの違いがあります。ダービーはregexp_likeをサポートしていないのでたとえば私のJPAクラスには、次のSQL文字列 JMockit Deencapsulation setField not persisting

定数
private static final String QUERY = "Select * from Users where regexp_like(user_code, '^SS(B)?N')"; 

を持っている私は、オンザフライでSQLを変更するJMockits Deencapsulation.setFieldを使用しています。例えば。

今では、実際のデータベース上で実行されます実際のクエリをテストしていないとして、これは(これは何が起こっているかのように私の好奇心を満たすために、純粋である)良いテストではないという事実を無視して
@Test 
public void testMyDaoFind() { 
    new Expectations() { 
     { 
      Deencapsulation.setField(MyClass.class, "QUERY", "Select * from Users"); 
     } 
    }; 

    dao.findUsers(); 
} 

、 Eclipselink/DerbyのSQL例外エラーが発生しました。regexp_likeが関数またはプロシージャとして認識されないという不具合があります。

私は結果のリストを取得しようとDAOでのライン上にブレークポイントを配置した場合、私は

  1. JMockitが正しくクエリ

  2. を置換していることを新しい時計から見ることができますgetResultListは()私はしかし、私はテストが、私はafformentioned例外を取得を通じて、すべての方法を実行してみましょう場合

を見て期待していたデータを返します!

答えて

2

Javaの文字列は、あなたが考えている方法では処理されません。 Javaソースコンパイラは、文字列リテラルを保持するフィールドの読み込みを、文字列が格納されている固定された「アドレス」(クラスの定数プール内)に置き換えます。実行時にフィールドはもう読み込まれません。したがって、たとえJMockitがフィールドに格納されている文字列参照を置き換えたとしても、フィールドを使用するクライアントコードではその参照が認識されないため、違いはありません。

(ところで、なぜ期待ブロック内Deencapsulatin.setFieldに電話を入れてテストはありますか?そのようなブロックが唯一の記録の期待のために意図されている...)

ボトムライン、あなたがしているものを達成する方法はありませんしようとしている。代わりに、統合テストにOracleデータベースを使用するか、すべてのSQLコードを移植可能にして、regexp_likeなどのRDBMS固有の機能を使用しないでください。

+0

非常に有益です! – PDStat

関連する問題