在使用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是
1
和2
,而预期的是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()
方法,那么结果将提供更多信息:java.lang.AssertionError:
Expected: iterable containing [hasProperty("id", is <1>), hasProperty("id", is <3>)]
but: item 0: property 'id' was <2>
不幸的是,由于没有排序Set,因此在这种情况下
contains()
并不是选项。最后一个问题:
使用hamcrest声明
Set
时,是否可以通过某种方式获得更好的错误报告? 最佳答案
对于如何报告contains
和containsInAnyOrder
匹配器的不匹配情况,Hamcrest似乎具有不同的实现方式。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
关于java - JUnit和Hamcrest : could containsInAnyOrder() tell more about the mismatch?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29652265/