JUnit& hamcrest:could containsInAnyOrder()告诉更多关于不匹配的事情?

时间:2015-04-15 13:57:35

标签: java unit-testing junit hamcrest

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

简单的bean:

public class MyBean {
    private Integer id;

    public Integer getId() {
        return id;
    }

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

JUnit测试:

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

正如您所见,实际的bean ID是12,而预期的是[{1}}和1,因此测试失败。

测试结果:

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()

不幸的是,由于未订购Set java.lang.AssertionError: Expected: iterable containing [hasProperty("id", is <1>), hasProperty("id", is <3>)] but: item 0: property 'id' was <2> 在这种情况下不是一个选项。


最后一个问题:
在使用hamcrest断言contains()时,是否有可能获得更好的错误报告?

1 个答案:

答案 0 :(得分:1)

Hamcrest似乎对containscontainsInAnyOrder匹配器的不匹配报告有不同的实现方式。

containsInAnyOrder只会通过这样做为您提供项目的toString()值:

mismatchDescription.appendText("Not matched: ").appendValue(item);

虽然contains匹配器通过委派给实际的匹配器describeMismatch()做得更好:

matcher.describeMismatch(item, mismatchDescription);

因此,在这种情况下,您会看到hasProperty匹配器的附加信息,但在使用containsInAnyOrder时却看不到。

我认为在这种情况下您可以做的最好的事情是为toString()课程实施MyBean

已经报道了这个问题:https://github.com/hamcrest/JavaHamcrest/issues/47