如何声明一个Iterable包含具有某个属性的元素?
假设我想用这个签名unit testing一个方法:
List<MyItem> getMyItems();  假设MyItem是一个有很多属性的Pojo,其中之一是通过getName()访问的"name" 。 
 我关心的是, List<MyItem>或任何Iterable包含两个MyItem实例,其"name"属性的值为"foo"和"bar" 。 如果任何其他属性不匹配,我真的不在乎这个testing的目的。 如果名字匹配,这是一个成功的testing。 
如果可能的话,我希望它是单行的。 这是我想做的事情的一些“伪语法”。
 assert(listEntriesMatchInAnyOrder(myClass.getMyItems(), property("name"), new String[]{"foo", "bar"}); 
Hamcrest会对这种事情有好处吗? 如果是这样,那么我的伪语法的最后一个版本是什么?
谢谢@拉赞夫指出我正确的方向。 我能够在一条线上得到它,并成功地追捕了Hamcrest 1.3的import货。
import:
 import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.contains; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.beans.HasPropertyWithValue.hasProperty; 
代码:
 assertThat( myClass.getMyItems(), contains( hasProperty("name", is("foo")), hasProperty("name", is("bar")) )); 
尝试:
 assertThat(myClass.getMyItems(), hasItem(hasProperty("YourProperty", is("YourValue")))); 
这不是特别Hamcrest,但我觉得这里值得一提。 我在Java8中经常使用的东西是这样的:
 assertTrue(myClass.getMyItems().stream().anyMatch(item -> "foo".equals(item.getName()))); 
(编辑Rodrigo Manyari的稍微改进,略less一点,详见评论)
可能有点难以阅读,但我喜欢types和重构的安全性。 它也很酷,用于组合testing多个bean属性。 例如在filterlambda中使用类似java的&&expression式。
Assertj擅长这一点。
 import static org.assertj.core.api.Assertions.assertThat; assertThat(myClass.getMyItems()).extracting("name").contains("foo", "bar"); 
与hamcrest相比,assertj的优点是可以很容易地使用代码完成。
只要你的List是一个具体的类,只要你在MyItem上实现了equals()方法,你可以直接调用contains()方法。
 // given // some input ... you to complete // when List<MyItems> results = service.getMyItems(); // then assertTrue(results.contains(new MyItem("foo"))); assertTrue(results.contains(new MyItem("bar"))); 
假设你已经实现了一个接受你想断言的值的构造函数。 我意识到这不是一个单一的行,但是知道哪个值丢失而不是一次检查两个是有用的。
我会用类似的东西
 String s = myClass.getMyItems().toString(); assertTrue(s.contains(", name=foo, ") && s.contains(", name=bar, "));