是否有一个 Hamcrest“ for each”Matcher 断言 Collection 或 Iterable 的所有元素都匹配一个特定的 Matcher?

给定项的 CollectionIterable,是否有任何 Matcher(或匹配器的组合)断言每个项匹配单个 Matcher

例如,给定此项类型:

public interface Person {
public String getGender();
}

我想写一个断言,说明 Person集合中的所有项目都有一个特定的 gender值。我是这么想的:

Iterable<Person> people = ...;
assertThat(people, each(hasProperty("gender", "Male")));

有没有什么办法可以不用自己写 each匹配程序就可以做到这一点?

31175 次浏览

使用 Every匹配器。

import org.hamcrest.beans.HasPropertyWithValue;
import org.hamcrest.core.Every;
import org.hamcrest.core.Is;
import org.junit.Assert;


Assert.assertThat(people, (Every.everyItem(HasPropertyWithValue.hasProperty("gender", Is.is("male")))));

Hamcrest 还提供 Matchers#everyItem作为通往 Matcher的快捷方式。


完整的例子

@org.junit.Test
public void method() throws Exception {
Iterable<Person> people = Arrays.asList(new Person(), new Person());
Assert.assertThat(people, (Every.everyItem(HasPropertyWithValue.hasProperty("gender", Is.is("male")))));
}


public static class Person {
String gender = "male";


public String getGender() {
return gender;
}


public void setGender(String gender) {
this.gender = gender;
}
}

恕我直言,这句话的可读性要高得多:

people.forEach(person -> Assert.assertThat(person.getGender()), Is.is("male"));

比批准的答案更容易理解,在一个循环中没有单独的断言:

import static org.assertj.core.api.Assertions.assertThat;


assertThat(people).allMatch((person) -> {
return person.gender.equals("male");
});