Search code examples
javaunit-testingmockito

Matching list in any order when mocking method behavior with Mockito


I have a test using Mockito that has a very strange behavior: it works in debug, but fails when running normally.

After some investigation, I realized it's because I am mocking methods behavior, passing a list of elements to match. But for some reason, order in the list is not always the same so it doesn't match and what I expect my mock to return is not returned, because the 2 lists are not "equals"

 when(mockStatusCalculatorService.calculateStatus(Arrays.asList(IN_PROGRESS, ABANDONED, EXPIRED))).thenReturn(ConsolidatedStatus.EXPIRED);

In my case, order of elements to match doesn't matter. So how can I specify this when configuring my mock?


Solution

  • If you have Mockito prior to version 2.1.0:

    Use the Hamcrest containsInAnyOrder matcher.

    when(myMock.myMethod(argThat(containsInAnyOrder(IN_PROGRESS, ABANDONED, EXPIRED))))
        .thenReturn(myValue);
    

    Thank you to @kolobok for pointing out that as from Mockito 2.1.0 (which came out after I wrote this answer), this no longer works.

    So for version 2.1.0 and above:

    add a dependency on Hamcrest, and use the MockitoHamcrest.argThat instead of Mockito.argThat

    More detail on the breaking change with Mockito 2.1.0 is at https://www.javadoc.io/doc/org.mockito/mockito-core/2.1.0/org/mockito/ArgumentMatcher.html