Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine multiple Mockito matchers with a logical "and"/"or"?

Tags:

mockito

I'd like to verify using Mockito that a string argument satisfies two conditions:

verify(mockClass).doSomething(Matchers.startsWith("prefix")); verify(mockClass).doSomething(Matchers.endsWith("suffix")); 

How to combine those two into one statement?

like image 468
Ilya Kogan Avatar asked Mar 20 '14 08:03

Ilya Kogan


People also ask

How do you use argument matchers in Mockito?

If you are using argument matchers, all arguments have to be provided by matchers. E.g: (example shows verification but the same applies to stubbing): verify(mock). someMethod(anyInt(), anyString(), eq("third argument")); //above is correct - eq() is also an argument matcher verify(mock).

Can the Mockito Matcher methods be used as return values?

Matcher methods can't be used as return values; there is no way to phrase thenReturn(anyInt()) or thenReturn(any(Foo. class)) in Mockito, for instance. Mockito needs to know exactly which instance to return in stubbing calls, and will not choose an arbitrary return value for you.

What can I use instead of Mockito matchers?

mockito. Matchers is deprecated, ArgumentMatchers should be used instead.


2 Answers

This is possible using org.mockito.AdditionalMatchers:

import static org.mockito.AdditionalMatchers.and;  verify(mockClass).doSomething(          and(Matchers.startsWith("prefix"),               Matchers.endsWith("suffix")); 

There are also org.mockito.AdditionalMatchers.or and org.mockito.AdditionalMatchers.not.

like image 113
Ilya Kogan Avatar answered Oct 11 '22 14:10

Ilya Kogan


Prior comments have called out that and takes only two arguments, and that having a variant that takes three or more would be advantageous. The following code solves this recursively, allowing multiple matchers to be specified in varargs:

public static String conjunction(String... matchers) {   if (matchers.length < 2) {     throw new IllegalArgumentException("matchers.length must be >= 2");   } else if (matchers.length == 2) {     return and(matchers[0], matchers[1]);   } else {     final String[] tail = new String[matchers.length - 1];     System.arraycopy(matchers, 1, tail, 0, tail.length);     return and(matchers[0], conjunction(tail));   } } 

assuming the following imports:

import static org.mockito.AdditionalMatchers.*; import static org.mockito.Mockito.*; 
like image 44
Emil Koutanov Avatar answered Oct 11 '22 14:10

Emil Koutanov