在Hamcrest中进行测试,该列表仅存在具有特定属性的列表中的一个项目

使用Hamcrest,我们可以轻松地测试存在具有特定属性的列表中的至少一个项目,例如

List myList = .... MatcherAssert.assertThat(myList, Matchers.hasItem(Matchers.hasProperty("fieldName", Matchers.equalTo("A funny string"))))); 

Pojo类是这样的:

 public class Pojo{ private String fieldName; } 

这很好,但是如何检查列表中是否只有一个具有特定属性的对象?

您可能必须为此编写自己的匹配器。 (我更喜欢fest断言和Mockito,但过去习惯使用Hamcrest …)

例如…

 import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.core.IsCollectionContaining; public final class CustomMatchers { public static  Matcher> exactlyNItems(final int n, Matcher elementMatcher) { return new IsCollectionContaining(elementMatcher) { @Override protected boolean matchesSafely(Iterable collection, Description mismatchDescription) { int count = 0; boolean isPastFirst = false; for (Object item : collection) { if (elementMatcher.matches(item)) { count++; } if (isPastFirst) { mismatchDescription.appendText(", "); } elementMatcher.describeMismatch(item, mismatchDescription); isPastFirst = true; } if (count != n) { mismatchDescription.appendText(". Expected exactly " + n + " but got " + count); } return count == n; } }; } } 

你现在可以做……

  List list = Arrays.asList(new TestClass("Hello"), new TestClass("World"), new TestClass("Hello")); assertThat(list, CustomMatchers.exactlyNItems(2, hasProperty("s", equalTo("Hello")))); 

列表为…时示例失败输出

  List list = Arrays.asList(new TestClass("Hello"), new TestClass("World")); 

…将会…

 Exception in thread "main" java.lang.AssertionError: Expected: a collection containing hasProperty("s", "Hello") but: , property 's' was "World". Expected exactly 2 but got 1 

(你可能想稍微调整一下)

顺便说一句,“TestClass”是……

 public static class TestClass { String s; public TestClass(String s) { this.s = s; } public String getS() { return s; } } 

Matchers.hasItems专门检查您提供的项目是否存在于集合中,您要查找的是Matchers.contains ,它确保2个集合基本相同 – 或者在您的情况下,根据提供的等价物

您还可以使用Predicate和filter :

 Predicate predicate = pojo -> pojo.getField().equals("funny string"); long nrOfElementsSatisfyingPredicate = myList.stream() .filter(predicate::test) .count(); assertEquals(1, nrOfElementsSatisfyingPredicate);