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

Jea*_*ean 10 java unit-testing hamcrest

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

List<Pojo> myList = ....

MatcherAssert.assertThat(myList, Matchers.hasItem(Matchers.<Pojo>hasProperty("fieldName", Matchers.equalTo("A funny string")))));
Run Code Online (Sandbox Code Playgroud)

这个类Pojo是这样的:

public class Pojo{
  private String fieldName;
}
Run Code Online (Sandbox Code Playgroud)

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

tdd*_*key 6

Matchers.hasItems特别检查您提供的项目是否存在于集合中,您要查找的是Matchers.contains确保这两个集合本质上相同 - 或者在您的情况下,根据提供的内容等效


Bre*_*etC 5

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

例如...

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.core.IsCollectionContaining;

public final class CustomMatchers {

    public static <T> Matcher<Iterable<? super T>> exactlyNItems(final int n, Matcher<? super T> elementMatcher) {
        return new IsCollectionContaining<T>(elementMatcher) {
            @Override
            protected boolean matchesSafely(Iterable<? super T> 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;
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

你现在可以做......

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

    assertThat(list, CustomMatchers.exactlyNItems(2, hasProperty("s", equalTo("Hello"))));
Run Code Online (Sandbox Code Playgroud)

列表为...时示例失败输出

    List<TestClass> list = Arrays.asList(new TestClass("Hello"), new TestClass("World"));
Run Code Online (Sandbox Code Playgroud)

...将会...

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
Run Code Online (Sandbox Code Playgroud)

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

顺便说一句,"TestClass"是......

public static class TestClass {
    String s;

    public TestClass(String s) {
        this.s = s;
    }

    public String getS() {
        return s;
    }
}
Run Code Online (Sandbox Code Playgroud)