断言Junit中的List

时间:2022-09-04 10:50:09

How to make assertions about a list in a JUnit test case? Not only the size of the list but also the contents of the list.

如何在JUnit测试用例中对列表进行断言?不仅列表的大小,而且列表的内容。

9 个解决方案

#1


114  

I realise this was asked a couple years ago, probably this feature wasn't around then. But now, it's easy to just do this:

我意识到这是几年前被问到的,可能这个功能不是那时候的。但是现在,这很容易做到:

@Test
public void test_array_pass()
{
  List<String> actual = Arrays.asList("fee", "fi", "foe");
  List<String> expected = Arrays.asList("fee", "fi", "foe");

  assertThat(actual, is(expected));
  assertThat(actual, is(not(expected)));
}

If you have a recent version of Junit installed with hamcrest, just add these imports:

如果您使用hamcrest安装了最新版本的Junit,只需添加以下导入:

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

http://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat(T, org.hamcrest.Matcher)

http://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat(T,org.hamcrest.Matcher)

http://junit.org/junit4/javadoc/latest/org/hamcrest/CoreMatchers.html

http://junit.org/junit4/javadoc/latest/org/hamcrest/CoreMatchers.html

http://junit.org/junit4/javadoc/latest/org/hamcrest/core/Is.html

http://junit.org/junit4/javadoc/latest/org/hamcrest/core/Is.html

#2


18  

This is a legacy answer, suitable for JUnit 4.3 and below. The modern version of JUnit includes a built-in readable failure messages in the assertThat method. Prefer other answers on this question, if possible.

这是一个传统的答案,适用于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));

For the record, as @Paul mentioned in his comment to this answer, two Lists are equal:

正如@Paul在对这个答案的评论中提到的那样,两个列表是相同的:

if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal. (Two elements e1 and e2 are equal if (e1==null ? e2==null : e1.equals(e2)).) In other words, two lists are defined to be equal if they contain the same elements in the same order. This definition ensures that the equals method works properly across different implementations of the List interface.

当且仅当指定的对象也是列表时,两个列表具有相同的大小,并且两个列表中的所有对应的元素对相等。 (如果(e1 == null?e2 == null:e1.equals(e2)),则两个元素e1和e2相等。)换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。此定义确保equals方法在List接口的不同实现中正常工作。

See the JavaDocs of the List interface.

请参阅List接口的JavaDocs。

#3


15  

Don't transform to string and compare. This is not good for perfomance. In the junit, inside Corematchers, there's a matcher for this => hasItems

不要转换为字符串并进行比较。这对于性能不利。在junit中,在Corematchers中,有一个匹配器=> hasItems

List<Integer> yourList = Arrays.asList(1,2,3,4)    
assertThat(yourList, CoreMatchers.hasItems(1,2,3,4,5));

This is the better way that I know of to check elements in a list.

这是我知道检查列表中元素的更好方法。

#4


7  

If you don't care about the order of the elements, I recommend ListAssert.assertEquals in junit-addons.

如果您不关心元素的顺序,我建议在junit-addons中使用ListAssert.assertEquals。

Link: http://junit-addons.sourceforge.net/

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

For lazy Maven users:

对于懒惰的Maven用户:

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

#5


3  

List<Integer> figureTypes = new ArrayList<Integer>(
                           Arrays.asList(
                                 1,
                                 2
                            ));

List<Integer> figureTypes2 = new ArrayList<Integer>(
                           Arrays.asList(
                                 1,
                                 2));

assertTrue(figureTypes .equals(figureTypes2 ));

#6


1  

Don't reinvent the wheel!

不要重新发明*!

There's a Google Code library that does this for you: Hamcrest

有一个Google代码库可以为您完成此任务:Hamcrest

[Hamcrest] Provides a library of matcher objects (also known as constraints or predicates) allowing 'match' rules to be defined declaratively, to be used in other frameworks. Typical scenarios include testing frameworks, mocking libraries and UI validation rules.

[Hamcrest]提供一个匹配器对象库(也称为约束或谓词),允许以声明方式定义“匹配”规则,以便在其他框架中使用。典型的场景包括测试框架,模拟库和UI验证规则。

#7


1  

if you don't want to build up an array list , you can try this also

如果您不想构建数组列表,也可以尝试这样做

@Test
public void test_array_pass()
{
  List<String> list = Arrays.asList("fee", "fi", "foe");
  Strint listToString = list.toString();
  Assert.assertTrue(listToString.contains("[fee, fi, foe]"));   // passes  
}

#8


1  

You can use assertEquals in junit.

您可以在junit中使用assertEquals。

import org.junit.Assert;   
import org.junit.Test;

    @Test
    public void test_array_pass()
    {
        List<String> actual = Arrays.asList("fee", "fi", "foe");
        List<String> expected = Arrays.asList("fee", "fi", "foe");
        Assert.assertEquals(actual,expected);
    }

If the order of elements is different then it will return error.

如果元素的顺序不同,那么它将返回错误。

If you are asserting a model object list then you should override the equals method in the specific model.

如果要断言模型对象列表,则应覆盖特定模型中的equals方法。

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj != null && obj instanceof ModelName) {
            ModelName other = (ModelName) obj;
            return this.getItem().equals(other.getItem()) ;
        }
        return false;
    }

#9


0  

I don't this the all the above answers are giving the exact solution for comparing two lists of Objects. Most of above approaches can be helpful in following limit of comparisons only - Size comparison - Reference comparison

我不是这个,所有上述答案都给出了比较两个对象列表的确切解决方案。以上大多数方法仅对以下比较限制有帮助 - 大小比较 - 参考比较

But if we have same sized lists of objects and different data on the objects level then this comparison approaches won't help.

但是,如果我们在对象级别上具有相同大小的对象列表和不同数据,那么这种比较方法将无济于事。

I think the following approach will work perfectly with overriding equals and hashcode method on the user-defined object.

我认为以下方法将完全适用于在用户定义的对象上覆盖equals和hashcode方法。

I used Xstream lib for override equals and hashcode but we can override equals and hashcode by out won logics/comparison too.

我使用Xstream lib来覆盖equals和hashcode,但是我们也可以通过out won logics / comparison来覆盖equals和hashcode。

Here is the example for your reference

以下是供您参考的示例

    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);
      }
    }

The most important thing is that you can ignore the fields by Annotation (@XStreamOmitField) if you don't want to include any fields on the equal check of Objects. There are many Annotations like this to configure so have a look deep about the annotations of this lib.

最重要的是,如果您不想在对象的相等检查中包含任何字段,则可以通过Annotation(@XStreamOmitField)忽略字段。有很多这样的注释要配置,所以要深入了解这个lib的注释。

I am sure this answer will save your time to identify the correct approach for comparing two lists of objects :). Please comment if you see any issues on this.

我相信这个答案将节省您的时间来确定比较两个对象列表的正确方法:)。如果您发现任何问题,请发表评论。

#1


114  

I realise this was asked a couple years ago, probably this feature wasn't around then. But now, it's easy to just do this:

我意识到这是几年前被问到的,可能这个功能不是那时候的。但是现在,这很容易做到:

@Test
public void test_array_pass()
{
  List<String> actual = Arrays.asList("fee", "fi", "foe");
  List<String> expected = Arrays.asList("fee", "fi", "foe");

  assertThat(actual, is(expected));
  assertThat(actual, is(not(expected)));
}

If you have a recent version of Junit installed with hamcrest, just add these imports:

如果您使用hamcrest安装了最新版本的Junit,只需添加以下导入:

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

http://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat(T, org.hamcrest.Matcher)

http://junit.org/junit4/javadoc/latest/org/junit/Assert.html#assertThat(T,org.hamcrest.Matcher)

http://junit.org/junit4/javadoc/latest/org/hamcrest/CoreMatchers.html

http://junit.org/junit4/javadoc/latest/org/hamcrest/CoreMatchers.html

http://junit.org/junit4/javadoc/latest/org/hamcrest/core/Is.html

http://junit.org/junit4/javadoc/latest/org/hamcrest/core/Is.html

#2


18  

This is a legacy answer, suitable for JUnit 4.3 and below. The modern version of JUnit includes a built-in readable failure messages in the assertThat method. Prefer other answers on this question, if possible.

这是一个传统的答案,适用于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));

For the record, as @Paul mentioned in his comment to this answer, two Lists are equal:

正如@Paul在对这个答案的评论中提到的那样,两个列表是相同的:

if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal. (Two elements e1 and e2 are equal if (e1==null ? e2==null : e1.equals(e2)).) In other words, two lists are defined to be equal if they contain the same elements in the same order. This definition ensures that the equals method works properly across different implementations of the List interface.

当且仅当指定的对象也是列表时,两个列表具有相同的大小,并且两个列表中的所有对应的元素对相等。 (如果(e1 == null?e2 == null:e1.equals(e2)),则两个元素e1和e2相等。)换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。此定义确保equals方法在List接口的不同实现中正常工作。

See the JavaDocs of the List interface.

请参阅List接口的JavaDocs。

#3


15  

Don't transform to string and compare. This is not good for perfomance. In the junit, inside Corematchers, there's a matcher for this => hasItems

不要转换为字符串并进行比较。这对于性能不利。在junit中,在Corematchers中,有一个匹配器=> hasItems

List<Integer> yourList = Arrays.asList(1,2,3,4)    
assertThat(yourList, CoreMatchers.hasItems(1,2,3,4,5));

This is the better way that I know of to check elements in a list.

这是我知道检查列表中元素的更好方法。

#4


7  

If you don't care about the order of the elements, I recommend ListAssert.assertEquals in junit-addons.

如果您不关心元素的顺序,我建议在junit-addons中使用ListAssert.assertEquals。

Link: http://junit-addons.sourceforge.net/

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

For lazy Maven users:

对于懒惰的Maven用户:

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

#5


3  

List<Integer> figureTypes = new ArrayList<Integer>(
                           Arrays.asList(
                                 1,
                                 2
                            ));

List<Integer> figureTypes2 = new ArrayList<Integer>(
                           Arrays.asList(
                                 1,
                                 2));

assertTrue(figureTypes .equals(figureTypes2 ));

#6


1  

Don't reinvent the wheel!

不要重新发明*!

There's a Google Code library that does this for you: Hamcrest

有一个Google代码库可以为您完成此任务:Hamcrest

[Hamcrest] Provides a library of matcher objects (also known as constraints or predicates) allowing 'match' rules to be defined declaratively, to be used in other frameworks. Typical scenarios include testing frameworks, mocking libraries and UI validation rules.

[Hamcrest]提供一个匹配器对象库(也称为约束或谓词),允许以声明方式定义“匹配”规则,以便在其他框架中使用。典型的场景包括测试框架,模拟库和UI验证规则。

#7


1  

if you don't want to build up an array list , you can try this also

如果您不想构建数组列表,也可以尝试这样做

@Test
public void test_array_pass()
{
  List<String> list = Arrays.asList("fee", "fi", "foe");
  Strint listToString = list.toString();
  Assert.assertTrue(listToString.contains("[fee, fi, foe]"));   // passes  
}

#8


1  

You can use assertEquals in junit.

您可以在junit中使用assertEquals。

import org.junit.Assert;   
import org.junit.Test;

    @Test
    public void test_array_pass()
    {
        List<String> actual = Arrays.asList("fee", "fi", "foe");
        List<String> expected = Arrays.asList("fee", "fi", "foe");
        Assert.assertEquals(actual,expected);
    }

If the order of elements is different then it will return error.

如果元素的顺序不同,那么它将返回错误。

If you are asserting a model object list then you should override the equals method in the specific model.

如果要断言模型对象列表,则应覆盖特定模型中的equals方法。

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj != null && obj instanceof ModelName) {
            ModelName other = (ModelName) obj;
            return this.getItem().equals(other.getItem()) ;
        }
        return false;
    }

#9


0  

I don't this the all the above answers are giving the exact solution for comparing two lists of Objects. Most of above approaches can be helpful in following limit of comparisons only - Size comparison - Reference comparison

我不是这个,所有上述答案都给出了比较两个对象列表的确切解决方案。以上大多数方法仅对以下比较限制有帮助 - 大小比较 - 参考比较

But if we have same sized lists of objects and different data on the objects level then this comparison approaches won't help.

但是,如果我们在对象级别上具有相同大小的对象列表和不同数据,那么这种比较方法将无济于事。

I think the following approach will work perfectly with overriding equals and hashcode method on the user-defined object.

我认为以下方法将完全适用于在用户定义的对象上覆盖equals和hashcode方法。

I used Xstream lib for override equals and hashcode but we can override equals and hashcode by out won logics/comparison too.

我使用Xstream lib来覆盖equals和hashcode,但是我们也可以通过out won logics / comparison来覆盖equals和hashcode。

Here is the example for your reference

以下是供您参考的示例

    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);
      }
    }

The most important thing is that you can ignore the fields by Annotation (@XStreamOmitField) if you don't want to include any fields on the equal check of Objects. There are many Annotations like this to configure so have a look deep about the annotations of this lib.

最重要的是,如果您不想在对象的相等检查中包含任何字段,则可以通过Annotation(@XStreamOmitField)忽略字段。有很多这样的注释要配置,所以要深入了解这个lib的注释。

I am sure this answer will save your time to identify the correct approach for comparing two lists of objects :). Please comment if you see any issues on this.

我相信这个答案将节省您的时间来确定比较两个对象列表的正确方法:)。如果您发现任何问题,请发表评论。