具有不同对象的自定义匹配器



嗨,我正在编写一个自定义匹配器来验证两个不同的对象,而我的代码是:

public class DetailsMatcher extends ArgumentMatcher <Details> {
    private final Details expected;
    private DetailsMatcher(Details expected) {
        this.expected = expected;
    }
    @Override
    public boolean matches(Object actual) {
        return ((Request) actual).getId().equals(expected.getId());
    }
    @Override
    public void describeTo(Description description) {
        description.appendText(expected == null ? null : expected.toString());
    }
    public static Details valueObjectEq(Details expected) {
        return argThat(new DetailsMatcher(expected));
    }
}

我想在测试中使用它:

assertThat(requestModel, DetailsMatcher.valueObjectEq(response));

,但这是两个不同的对象,因此它不起作用。我不想仅仅为了测试目的更改对象,所以我们是否有一些API,例如断言,它允许传递不同的对象简单地依赖匹配的输出,而不是强迫同一类型的实际和预期?

请小心地将Mockito Matchers和Hamcrest Matchers分开。hamcrest或hamcrest风格的匹配器是一个对象实例,就像上面的new DetailsMatcher(expected)一样。通过调用argThat,您的valueObjectEq似乎返回Details对象,但这不是事实:它将返回null,Mockito将在内部堆栈中保存对象。因此,您切勿在致电whenverify之外致电argThat

相反,将您的详细信息更改为类型ArgumentMatcher<Request>,以指示您的匹配器可以在任何Request上使用,而不仅仅是Details,并将构造函数公开,因此您可以这样称呼它:

assertThat(requestModel, new DetailsMatcher(orderResponse));
// or with a static helper method you write:
assertThat(requestModel, matchesValueObject(orderResponse));

其他一些注释:

  • Matcher.matches永远不要抛出异常,但是如果您通过非要求,它将在这里这样做。如果参数不是匹配器,请与instanceof检查并返回false
  • Mockito 2.0使参数匹配者自己的类,而不是扩展org.hamcrest.Matcher。如果您想继续使用匹配器作为其hamcrest属性,则可能需要将其两者都扩展,或者只是使其成为Hamcrest Matcher,然后调整valueObjectEq以致电MockitoHamcrest.argthat。
  • 尽管错误消息不会那么清楚,但您始终可以手动调用该方法:

    assertTrue(new DetailsMatcher(orderReponse).matches(requestModel));
    

另请参见:

  • Mockito的比赛与Hamcrest Matcher?
  • Mockito Matchers如何工作?

相关内容

  • 没有找到相关文章

最新更新