I have created a ArgumentMatcher
,
private class IsListOf2Elements implements ArgumentMatcher<List<String>>{
@Override
public boolean matches(List<String> argument) {
return ((List<String>)argument).size()==2;
}
}
I want to negate this match, so match when size is not 2,
Mockito.doReturn(false).when(mock).addAll(Mockito.argThat(AdditionalMatchers.not(new IsListOf2Elements())));
But this is not correct. I get,
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
No matchers found for additional matcher Not(?)
-> at my.test.own.Mockito_aTest.test4e(Mockito_aTest.java:136)
Mockito uses equal() as a legacy method for verification and matching of argument values. In some cases, we need more flexibility during the verification of argument values, so we should use argument matchers instead of equal() method. The ArgumentMatchers class is available in org. mockito package.
mockito. Matchers is deprecated, ArgumentMatchers should be used instead.
The argThat argument matcher in Mockito lets you create advanced argument matchers that run a function on passed arguments, and checks if the function returns true . If you have a complicated class that can't be easily checked using . equals() , a custom matcher can be a useful tool.
capture() it stores a matcher that saves its argument instead for later inspection. Matchers return dummy values such as zero, empty collections, or null . Mockito tries to return a safe, appropriate dummy value, like 0 for anyInt() or any(Integer. class) or an empty List<String> for anyListOf(String.
For reference, be aware that Hamcrest matchers and Mockito matchers behave very differently. Hamcrest's stateless Matcher objects represent the match function as an instance, and can be wrapped to invert their results; Mockito's "registered matchers" work only via side-effects.
argThat
adapts a Hamcrest matcher into a Mockito matcher, Hamcrest's CoreMatchers.not
inverts a Hamcrest matcher, and Mockito's AdditionalMatchers.not
inverts a Mockito matcher (via side-effects). This is part of the reason that CoreMatchers.not
always returns a Matcher<T>
, while AddionalMatchers.not
returns an arbitrary T
; it's operating on Mockito state you can't see.
This gives you the following behavior:
// 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())));
If the exception you're making is about stubbed behavior, you can also use a more-specific override to stub the general behavior in addition to the specific exception.
It seems to be that you cannot use a custom matcher as AdditionalMatchers.not
method parameter.
However, you can use hamcrest org.hamcrest.CoreMatchers instead. This should work:
Mockito.doReturn(false).when(mock).addAll(Mockito.argThat(CoreMatchers.not(new IsListOf2Elements())));
Hope it helps
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With