[java] 在Junit中聲明一個List



Answers

這是一個傳統的答案,適用於JUnit 4.3及更低版本。 現代版本的JUnit在assertThat方法中包含內置可讀的失敗消息。 如果可能的話,優先選擇其他答案。

List<E> a = resultFromTest();
List<E> expected = Arrays.asList(new E(), new E(), ...);
assertTrue("Expected 'a' and 'expected' to be equal."+
            "\n  'a'        = "+a+
            "\n  'expected' = "+expected, 
            expected.equals(a));

作為@Paul在他對這個答案的評論中提到的記錄,兩個List是相同的:

當且僅當指定的對像也是一個列表時,兩個列表都具有相同的大小,並且兩個列表中的所有相應元素對都相等。 (如果(e1==null ? e2==null : e1.equals(e2))兩個元素e1e2是相等的。)換句話說,如果兩個列表按照相同的順序包含相同的元素,則它們被定義為相等。 該定義確保了equals方法在List接口的不同實現之間正常工作。

請參閱List接口JavaDocs

Question

如何在JUnit測試用例中對列表進行斷言? 不僅列表的大小,而且列表的內容。




如果你不關心元素的順序,我推薦ListAssert.assertEquals junit-addons中的ListAssert.assertEquals

鏈接: http://junit-addons.sourceforge.net/ : http://junit-addons.sourceforge.net/

對於懶惰的Maven用戶:

    <dependency>
        <groupId>junit-addons</groupId>
        <artifactId>junit-addons</artifactId>
        <version>1.4</version>
        <scope>test</scope>
    </dependency>



不要重新發明輪子!

有一個谷歌代碼庫為你做這件事: Hamcrest

[Hamcrest]提供一個matcher對像庫(也稱為約束或謂詞),允許“匹配”規則以聲明的方式定義,以用於其他框架。 典型的場景包括測試框架,模擬庫和UI驗證規則。




我不是所有上述答案都提供了比較兩個對象列表的確切解決方案。 以上大多數方法僅可用於比較限制比較 - 大小比較 - 參考比較

但是,如果我們在對象級別上有相同大小的對象列表和不同數據,那麼這種比較方法將無濟於事。

我認為以下方法可以在用戶定義的對像上重寫equals和hashcode方法。

我使用Xstream lib來覆蓋equals和hashcode,但我們可以通過out won邏輯/比較覆蓋equals和hashcode。

以下是供您參考的例子

    import com.thoughtworks.xstream.XStream;

    import java.text.ParseException;
    import java.util.ArrayList;
    import java.util.List;

    class TestClass {
      private String name;
      private String id;

      public void setName(String value) {
        this.name = value;
      }

      public String getName() {
        return this.name;
      }

      public String getId() {
        return id;
      }

      public void setId(String id) {
        this.id = id;
      }

      /**
       * @see java.lang.Object#equals(java.lang.Object)
       */
      @Override
      public boolean equals(Object o) {
        XStream xstream = new XStream();
        String oxml = xstream.toXML(o);
        String myxml = xstream.toXML(this);

        return myxml.equals(oxml);
      }

      /**
       * @see java.lang.Object#hashCode()
       */
      @Override
      public int hashCode() {
        XStream xstream = new XStream();
        String myxml = xstream.toXML(this);
        return myxml.hashCode();
      }
    }

    public class XstreamCompareTest {
      public static void main(String[] args) throws ParseException {
      checkObjectEquals();
}

      private static void checkObjectEquals() {
        List<TestClass> testList1 = new ArrayList<TestClass>();
        TestClass tObj1 = new TestClass();
        tObj1.setId("test3");
        tObj1.setName("testname3");
        testList1.add(tObj1);

        TestClass tObj2 = new TestClass();
        tObj2.setId("test2");
        tObj2.setName("testname2");
        testList1.add(tObj2);

        testList1.sort((TestClass t1, TestClass t2) -> t1.getId().compareTo(t2.getId()));

        List<TestClass> testList2 = new ArrayList<TestClass>();
        TestClass tObj3 = new TestClass();
        tObj3.setId("test3");
        tObj3.setName("testname3");
        testList2.add(tObj3);

        TestClass tObj4 = new TestClass();
        tObj4.setId("test2");
        tObj4.setName("testname2");
        testList2.add(tObj4);

        testList2.sort((TestClass t1, TestClass t2) -> t1.getId().compareTo(t2.getId()));

        if (isNotMatch(testList1, testList2)) {
          System.out.println("The list are not matched");
        } else {
          System.out.println("The list are matched");
        }

      }

      private static boolean isNotMatch(List<TestClass> clist1, List<TestClass> clist2) {
        return clist1.size() != clist2.size() || !clist1.equals(clist2);
      }
    }

最重要的是,如果您不想在對象的相等檢查中包含任何字段,則可以通過Annotation(@XStreamOmitField)忽略這些字段。 有很多這樣的註解來配置,所以深入了解這個lib的註釋。

我相信這個答案會節省你的時間,以確定比較兩個對象列表的正確方法:)。 如果您發現任何問題,請發表評論。




Related