Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mockito - Is there a matcher for "value not in List"?

I currently have a mock which has specific behaviors for specific set of inputs. Every other input should return a specific response.

For example:

    Mockito.when(classInstance.myFunc(Mockito.eq("Option1"))).thenReturn(answer1);
    Mockito.when(classInstance.myFunc(Mockito.eq("Option2"))).thenReturn(answer2);
    Mockito.when(classInstance.myFunc(Mockito.eq("Option3"))).thenReturn(answer3);
    Mockito.when(classInstance.myFunc(Mockito.eq("Option4"))).thenReturn(answer4);

    // Return defaultAnswer if and(and(not("Option1"), not("Option2")), and(not("Option3"), not("Option4")))
    Mockito.when(classInstance.myFunc(AdditionalMatchers.and(AdditionalMatchers.and(AdditionalMatchers.not(Mockito.eq("Option1")), AdditionalMatchers.not(Mockito.eq("Option2")), AdditionalMatchers.and(AdditionalMatchers.not(Mockito.eq("Option3")), AdditionalMatchers.not(Mockito.eq("Option4")))).thenReturn(defaultAnswer);

My biggest trouble is the complexity of the and(and(not("Option1"), not("Option2")), and(not("Option3"), not("Option4"))) line.

I really hope that there is an easier way to specify a condition of "everything else" or just "not in list:["option1", ...] "

Is there a matcher for "Within a group" or something similar?

like image 939
GuyKhmel Avatar asked Oct 25 '25 00:10

GuyKhmel


2 Answers

You could probably make it a bit more readable by defining the default explicitly, then 'overriding' this with subsequent stubbings:

when(classInstance.myFunc(any()).thenReturn(defaultAnswer);
when(classInstance.myFunc("Option1").thenReturn(answer1);
when(classInstance.myFunc("Option2").thenReturn(answer2);
...

Or you could use MockitoHamcrest and Hamcrest's core matchers to simplify it a bit, e.g.:

when(classInstance.myFunc(argThat(is(allOf(not("Option1"), not("Option2"), ...))))
    .thenReturn(...)

Or you could use MockitoHamcrest and your own Hamcrest matcher.

like image 106
ryanp Avatar answered Oct 26 '25 14:10

ryanp


Why not simply use Mockito.matches(boolean) such as :

 import static org.mockito.Mockito.*;

 Mockito.when(classInstance.myFunc(matches("Option[^1-4]"))
        .thenReturn(defaultAnswer);

As alternative you can also use Mockito.argThat().
To filter out some integer values (as suggested in your comment) you could write :

 import static org.mockito.Mockito.*;

 List<Integer> toNotMatchList = Arrays.asList(1, 2, 3, 4) ;
 Mockito.when(classInstance.myFunc(argThat(i -> !toNotMatchList.contains(i))
        .thenReturn(defaultAnswer);

or more straightly :

Mockito.when(classInstance.myFunc(argThat(i -> !Arrays.asList(1, 2, 3, 4).contains(i))
        .thenReturn(defaultAnswer);
like image 43
davidxxx Avatar answered Oct 26 '25 14:10

davidxxx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!