Java JUnit&;hamcrest:ContainesAnyOrder()能告诉我们更多关于不匹配的信息吗?

Java JUnit&;hamcrest:ContainesAnyOrder()能告诉我们更多关于不匹配的信息吗?,java,unit-testing,junit,hamcrest,Java,Unit Testing,Junit,Hamcrest,在使用JUnit测试集时,我注意到Matchers.contains()方法提供了一个关于测试错误的非常好的线索。另一方面,Matchers.containsInAnyOrder()差异报告几乎是无用的。以下是测试代码: 简单bean: public class MyBean { private Integer id; public Integer getId() { return id; } public void setId(Integer

在使用JUnit测试
集时,我注意到
Matchers.contains()
方法提供了一个关于测试错误的非常好的线索。另一方面,
Matchers.containsInAnyOrder()
差异报告几乎是无用的。以下是测试代码:

简单bean:

public class MyBean {
    private Integer id;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }       
}
import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

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

public class MyTest {

    @Test
    public void hamcrestTest() {
        Set<MyBean> beanSet = new HashSet<MyBean>();

        MyBean bean = new MyBean();
        bean.setId(1);
        beanSet.add(bean);

        bean = new MyBean();
        bean.setId(2);
        beanSet.add(bean);

        assertThat(beanSet, contains(
                hasProperty("id", is(1)),
                hasProperty("id", is(3))
                ));
    }
}
java.lang.AssertionError: 
Expected: iterable over [hasProperty("id", is <1>), hasProperty("id", is <3>)] in any order
     but: Not matched: <MyBean@4888884e
JUnit测试:

public class MyBean {
    private Integer id;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }       
}
import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

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

public class MyTest {

    @Test
    public void hamcrestTest() {
        Set<MyBean> beanSet = new HashSet<MyBean>();

        MyBean bean = new MyBean();
        bean.setId(1);
        beanSet.add(bean);

        bean = new MyBean();
        bean.setId(2);
        beanSet.add(bean);

        assertThat(beanSet, contains(
                hasProperty("id", is(1)),
                hasProperty("id", is(3))
                ));
    }
}
java.lang.AssertionError: 
Expected: iterable over [hasProperty("id", is <1>), hasProperty("id", is <3>)] in any order
     but: Not matched: <MyBean@4888884e
如果我切换到
Matchers.contains()
方法,则结果的信息量会大得多:

java.lang.AssertionError: 
Expected: iterable containing [hasProperty("id", is <1>), hasProperty("id", is <3>)]
     but: item 0: property 'id' was <2>
java.lang.AssertionError:
应为:iterable包含[hasProperty(“id”,is),hasProperty(“id”,is)]
但是:项0:属性“id”为
不幸的是,由于集合没有排序,
contains()
在这种情况下不是选项


最后是问题:

在使用hamcrest断言
集合时,是否有可能获得更好的错误报告?

hamcrest对于
包含
包含任意顺序
匹配器的不匹配报告方式似乎有不同的实现

containsInAnyOrder
通过执行以下操作,仅为您提供项目的
toString()
值:

mismatchDescription.appendText("Not matched: ").appendValue(item);
包含
匹配器时,通过将任务委托给实际匹配器的
描述不匹配()
,匹配器的工作会更好:

因此,在本例中可以看到
hasProperty
matcher的附加信息,但在使用
containsInAnyOrder
时不会看到

我认为在这种情况下,最好是为
MyBean
类实现
toString()


关于这一点,已经有一个问题被报道了:

如果你在MyBean中添加一个toString方法,你应该会得到更好的输出…考虑到我有很多复杂的Bean实现
toString
将需要相当大的努力。不幸的是,在Hamcrest的当前状态下,我看不到其他方法。据报道,还有一个问题: