2009-06-03 3 views
1

私はメモリ内のHSQLDBを使ってJUnitテストを実行しています。 DBにいくつかの値を挿入するメソッドがあり、メソッドが値を正しく挿入したかどうかを確認しています。挿入の順序は重要ではないことに注意してください。ユニットテスト中のエンティティとHibernateの比較

@Test 
public void should_insert_correctly() { 
    MyEntity[] expectedEntities = new MyEntity[2]; 
    // init expected entities 

    Inserter out = new Inserter(session); // out: object under test 
    out.insert(); 

    List list = session.createCriteria(MyEntity.class).list(); 

    assertTrue(list.contains(expectedEntities[0])); 
    assertTrue(list.contains(expectedEntities[1])); 
} 

問題が予想されるのidとの実際のIDが異なっているので、私は現実のものに期待するエンティティを比較することはできませんです。 MyEntityのsetId()はプライベート(設定IDを明示的に禁止するため)であるため、すべてのエンティティのIDを0に設定してそのように比較することはできません。

IDに関係なく2つの結果セットを比較するにはどうすればよいですか?

+0

MyEntityクラスには、値に関する情報を追加してください。あなたにプライマリキーを与えるメンバーがいますか? – guerda

答えて

2

これはより実用的であることがわかりました。一度にすべての結果をフェッチするのではなく、基準に基づいて結果をフェッチして、それらがヌルではないと主張しています。

public void should_insert_correctly() { 
    Inserter out = new Inserter(session); // out: object under test 
    out.insert(); 

    Criteria criteria; 

    criteria = getCriteria(session, 0); 
    assertNotNull(criteria.uniqueResult()); 

    criteria = getCriteria(session, 1); 
    assertNotNull(criteria.uniqueResult()); 
} 

private Criteria getCriteria(Session session, int i) { 
    Criteria criteria = session.createCriteria(MyEntity.class); 
    criteria.add(Restrictions.eq("x", expectedX[i])); 
    criteria.add(Restrictions.eq("y", expectedY[i])); 
    return criteria; 
} 
0

ステートフルなエンティティはequalsをオーバーライドするべきではありません。つまり、エンティティは参照アイデンティティによって等しいかどうか比較する必要があります。List.containsは必要に応じて機能しません。

私が行うことは、オリジナルのエンティティと再読み込みされたエンティティのフィールドを比較するためにリフレクションを使用することです。オブジェクトのフィールドを移動する関数は、一時的なフィールドと@Transientとして注釈が付けられたフィールドを無視します。

私はidを無視する必要がありません。オブジェクトが最初にデータベースにフラッシュされるとき、Hibernateはそれをidに割り当てます。リロードされると、オブジェクトは同じIDを持ちます。

テストの脆弱性は、トランザクションの境界を設定していないことです。 1つのトランザクションでオブジェクトを保存する必要があります。そのトランザクションをコミットすると、Hibernateはオブジェクトをデータベースにフラッシュし、そのIDを割り当てます。次に、別のトランザクションでエンティティをデータベースからロードし直します。同じIDと持続的な(つまり非一時的な)状態を持つべき別のオブジェクトセットが得られます。

+0

expectedEntities 'と実際にインサートされたエンティティのIDが異なることに注意してください。私はexpectedEntitiesを保存していないので、私はする必要はありません。 – nimcap

+0

次に、オブジェクトの永続フィールドに反映するときにIDを無視します。 – Nat

+0

ステートフルエンティティがequalsをオーバーライドしないのはなぜですか?それを知らない。 – guerda

-1

MyEntityクラスにObject.equals(Object)メソッドを実装しようとします。

List.contains(Object)は、Object.equals(Object)(出典:)を使用して、オブジェクトがこのリストに含まれているかどうかを判断します。

あなたが挿入された値(たぶん)で新しいインスタンスのリストを返すsession.createCriteria(MyEntity.class).list();方法。
したがって、値を比較する必要があります。これは、Object.equals(Object)の実装によって簡単に実行できます。

明確化編集:
比較が唯一の「本当の価値」を気にするようにあなたがあなたのequals方法でIDを無視することができます。

YAE(もう一つの編集):Angelika Langer: Secrets Of Equal
私はequals()方法については、この記事を読んでお勧めします。すべての背景情報を非常によく説明します。

+0

私はequals()でidsを無視するのは良い解決策ではありません。将来もIDを比較する必要がある場合はどうなるのですか? – nimcap

+0

equals()メソッドを変更してIDの比較を統合するだけです。あなたが今日書いたテストは失敗します! – guerda

+0

ところで:なぜdownvote? – guerda

関連する問題