2016-04-30 12 views
0

私が作業しているプロジェクトでは、テストアサーションのためのfestの使用をやめ、代わりにassertjを使用することに決めました。私たちはJava 7を使用しており、フェストバージョン2.0M10からアサルトコアバージョン2.4.1に移行しています。コードベースはかなり大きいですが、festからassertjへの移行はスムーズで、基本的にインポート名が変更され、名前が変更されたメソッドに対処しています。 しかし、私は、移行後に特定のテストクラスでテスト失敗が発生していることに気付きました(私たちはJUnit v4.12を追加するべきです)。以下では、問題を浮き彫りにした小さな自己テストケースを示します。festとassert-jのカスタムマップの微妙な違い

import java.util.Collection; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.Set; 

import org.junit.Before; 
import org.junit.Test; 

class MyMap implements Map<String, Object> { 
    private Map<String, Object> theMap = new HashMap<>(); 

    @Override 
    public int size() { 
     return theMap.size(); 
    } 

    @Override 
    public boolean isEmpty() { 
     return theMap.isEmpty(); 
    } 

    @Override 
    public boolean containsKey(Object key) { 
     return theMap.containsKey(key); 
    } 

    @Override 
    public boolean containsValue(Object value) { 
     return theMap.containsValue(value); 
    } 

    @Override 
    public Object get(Object key) { 
     return theMap.get(key); 
    } 

    @Override 
    public Object put(String key, Object value) { 
     return theMap.put(key, value); 
    } 

    @Override 
    public Object remove(Object key) { 
     return theMap.remove(key); 
    } 

    @Override 
    public void putAll(Map<? extends String, ? extends Object> m) { 
     theMap.putAll(m); 
    } 

    @Override 
    public void clear() { 
     theMap.clear(); 
    } 

    @Override 
    public Set<String> keySet() { 
     return theMap.keySet(); 
    } 

    @Override 
    public Collection<Object> values() { 
     return theMap.values(); 
    } 

    @Override 
    public Set<java.util.Map.Entry<String, Object>> entrySet() { 
     return theMap.entrySet(); 
    } 
} 

public class TestMapComparison { 
    private Map<String, Object> m1 = new HashMap<>(); 
    private MyMap m2 = new MyMap(); 

    @Before 
    public void before() { 
     m1.put("a", "b"); 
     m2.put("a", "b"); 
    } 

    // Fails with: 
    // java.lang.AssertionError: 
    // expected: <'{'a'='b'} ([email protected])'> 
    // but was: <'{'a'='b'} ([email protected])'> 
    @Test 
    public void test1_Fest_m1_isEqualTo_m2() { 
     org.fest.assertions.api.Assertions.assertThat(m1).isEqualTo(m2); 
    } 

    @Test // Pass 
    public void test2_AssertJ_m1_isEqualTo_m2() { 
     org.assertj.core.api.Assertions.assertThat(m1).isEqualTo(m2); 
    } 

    @Test // Pass 
    public void test3_Fest_m2_isEqualTo_m1() { 
     org.fest.assertions.api.Assertions.assertThat(m2).isEqualTo(m1); 
    } 

    // Fails with: 
    // java.lang.AssertionError: 
    // Expecting: <"{"a"="b"} ([email protected])"> 
    // to be equal to: 
    // <"{"a"="b"} ([email protected])"> but was not. 
    @Test 
    public void test4_AssertJ_m2_isEqualTo_m1() { 
     org.assertj.core.api.Assertions.assertThat(m2).isEqualTo(m1); 
    } 
} 

このような長いコードは申し訳ありません。テスト結果からわかるように、ハッシュマップでisEqualTo()を使用している場合、festとassertjの間に違いがあるようです。ハッシュマップの1つは、インタフェースマップを実装するクラスにカプセル化されています。 私の質問はこれをどう対処するかです。 assertThat(a).isEqualTo(b)を持つ代わりに、assertThat(b).isEqualTo(a)というアサーションで順序を入れ替えることができます。しかし、それは私には、私は多くのアサーションを持つ大きなテストクラスで特定のアサーションでそのようなフリップ1をしなければならないことは少し変わったと感じています。 festとassertjの違いは予期されているか予期していませんか? (どちらも1つの式に失敗するので)どちらからも動作が期待されますか?テストケースをどのように更新すればよいですか?上記のコードのシナリオと同等のチェックを行う方が良いでしょうか?これまで読んでくれてありがとう、何かアドバイスありがとう!

答えて

2

まあ、バグがあなたのコードであり、そしてあなたが対等の契約を(テストした場合の各ライブラリは、バグを見つけるだろう)、ウィッヒは対称である必要があります:AはBのIFF Bは私が単にだろうA.

に等しい等しいですあなたのコードを修正し、移行のおかげでバグを発見して喜んでください。また、テストを改善して、契約が成立していることを確認するために、

assertThat(a).isEqualTo(b); 
assertThat(b).isEqualTo(a); 

を実行します。

+0

もちろん、ありがとうございます。私はテストを強化し、実際のクラスを見て、どこに問題があるかを見ていきます。再度、感謝します。 –

関連する問題