如何否定Mockito中的ArgumentMatcher?

时间:2016-10-24 10:18:18

标签: mocking mockito

我创建了ArgumentMatcher

private class IsListOf2Elements implements ArgumentMatcher<List<String>>{
    @Override
    public boolean matches(List<String> argument) {
        return ((List<String>)argument).size()==2;
    }
}

我想否定这个匹配,所以匹配大小不是2,

Mockito.doReturn(false).when(mock).addAll(Mockito.argThat(AdditionalMatchers.not(new IsListOf2Elements())));

但这不正确。我明白了,

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: 
No matchers found for additional matcher Not(?)
-> at my.test.own.Mockito_aTest.test4e(Mockito_aTest.java:136)

3 个答案:

答案 0 :(得分:4)

供参考,请注意Hamcrest matchers and Mockito matchers behave very differently。 Hamcrest的无状态匹配器对象将匹配函数表示为一个实例,并且可以将其包装以反转其结果; Mockito&#34;注册匹配者&#34;只能通过副作用来工作。

argThat将Hamcrest匹配器调整为Mockito匹配器,Hamcrest的CoreMatchers.not反转Hamcrest匹配器,而Mockito的AdditionalMatchers.not反转Mockito匹配器(通过侧面)效果 - )。这是CoreMatchers.not始终返回Matcher<T>,而AddionalMatchers.not返回任意T的部分原因;它在Mockito州经营,你无法看到。

这会给您以下行为:

// BAD: Don't use AdditionalMatchers to invert a Hamcrest matcher.
doReturn(false).when(mock).addAll(
    Mockito.argThat(AdditionalMatchers.not(new IsListOf2Elements())));

// GOOD: Use AdditionalMatchers to invert a Mockito matcher. (See ericj's answer.)
doReturn(false).when(mock).addAll(
    AdditionalMatchers​.not(Mockito.argThat‌​(new IsListOf2Elements())));

// ALSO GOOD: Use CoreMatchers to invert a Hamcrest matcher. (See troig's answer.)
doReturn(false).when(mock).addAll(
    Mockito.argThat‌​(CoreMatchers.not(new IsListOf2Elements())));

如果您所做的异常是关于存根行为的,那么除了特定的例外之外,您还可以使用more-specific override来存储一般行为。

答案 1 :(得分:1)

似乎您不能将自定义匹配器用作AdditionalMatchers.not方法参数。

但是,您可以使用hamcrest org.hamcrest.CoreMatchers代替。这应该有效:

Mockito.doReturn(false).when(mock).addAll(Mockito.argThat(CoreMatchers.not(new IsListOf2Elements())));

希望有所帮助

答案 2 :(得分:0)

我自己找到了答案。转身就是,

Mockito.doReturn(false).when(mock).addAll(AdditionalMatchers‌​.not(Mockito.argThat‌​(new IsListOf2Elements())));

原因是AdditionalMatchers‌​.not期望注册的匹配器,而Mockito.argThat‌确实这样做。