如何在Mockito中撤销ArgumentMatcher



我已经创建了一个ArgumentMatcher

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

我想否定这个匹配,所以当size不是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)

作为参考,请注意Hamcrest匹配器和Mockito匹配器的行为非常不同。Hamcrest的无状态Matcher对象将match函数表示为一个实例,并且可以通过包装来反转它们的结果;Mockito的"注册匹配器"只能通过副作用来工作。

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())));

如果你的异常是关于存根行为的,你还可以使用一个更具体的覆盖来存根一般的行为,除了特定的异常。

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

然而,你可以使用hamcrest org.hamcrest.CoreMatchers代替。这应该可以工作:

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

希望有所帮助

我自己找到了答案。Turn is around,

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

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

就这样写:

AdditionalMatchers.not(ArgumentMatchers.eq(...)

相关内容

  • 没有找到相关文章

最新更新