Лучший способ (ИМО), чтобы сделать это было бы объединить перегруженный containsInAnyOrder
Искателя вместе с обычаем FeatureMatcher
. В конечном счете ваш код будет выглядеть следующим образом:
String[] expectedNames = new String[] { "John", "Bob", "Carol"};
assertThat(savedGroup.getMembers(), hasNames(expectedNames));
hasNames
реализуется следующим образом:
private Matcher<Iterable<? extends Member>> hasNames(String[] expectedNames) {
return containsInAnyOrder(Arrays.stream(expectedNames).map(name -> name(name)).collect(Collectors.toList()));
}
И заключительная часть вызова name
, который генерирует Искатель, который будет извлекать недвижимость в типа- безопасный путь от вашего объекта:
private Matcher<Member> name(String name) {
return new FeatureMatcher<Member, String>(equalTo(name), "name", "name") {
@Override
protected String featureValueOf(Member actual) {
return actual.getName();
}
};
}
преимущество делать это, это способ заключается в следующем:
- Вы получаете преимущество безопасности типов вместо использования
hasProperty
- Вашего теста описывает то, что вы хотите, чтобы фактический матч на, т.е.
hasNames
- Код производится теперь более гибкий и компонуем. Хотите совместить имя одного объекта? Все, что вам теперь нужно сделать, это
assertThat(member, has(name("Fred")))
Вы можете получить еще больше компонуемости, перемещая equalTo
суб-Искателя быть частью hasNames называют так:
private Matcher<Iterable<? extends Member>> hasNames(String[] expectedNames) {
return containsInAnyOrder(Arrays.stream(expectedNames).map(name -> name(equalTo(name))).collect(Collectors.toList()));
}
private Matcher<Member> name(Matcher<String> nameMatcher) {
return new FeatureMatcher<Member, String>(nameMatcher, "name", "name") {
@Override
protected String featureValueOf(Member actual) {
return actual.getName();
}
};
}