Mockito; verify method was called with list, ignore order of elements in list

As noted in another answer, if you don't care about the order, you might do best to change the interface so it doesn't care about the order.

If order matters in the code but not in a specific test, you can use the ArgumentCaptor as you did. It clutters the code a bit.

If this is something you might do in multiple tests, you might do better to use appropriate Mockito Matchers or Hamcrest Matchers, or roll your own (if you don't find one that fills the need). A hamcrest matcher might be best as it can be used in other contexts besides mockito.

For this example you could create a hamcrest matcher as follows:

import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;

import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class MyMatchers {
    public  static <T> Matcher<List<T>> sameAsSet(final List<T> expectedList) {
        return new BaseMatcher<List<T>>(){
            @Override
            public boolean matches(Object o) {
                List<T> actualList = Collections.EMPTY_LIST;
                try {
                    actualList = (List<T>) o;
                }
                catch (ClassCastException e) {
                    return false;
                }
                Set<T> expectedSet = new HashSet<T>(expectedList);
                Set<T> actualSet = new HashSet<T>(actualList);
                return actualSet.equals(expectedSet);
            }

            @Override
            public void describeTo(Description description) {
                description.appendText("should contain all and only elements of ").appendValue(expectedList);
            }
        };
    }
}

And then the verify code becomes:

verify(mockClassB).sendEvent(argThat(MyMatchers.sameAsSet(expectedFileList)));

If you instead created a mockito matcher, you wouldn't need the argThat, which basically wraps a hamcrest matcher in a mockito matcher.

This moves the logic of sorting or converting to set out of your test and makes it reusable.


An ArgumentCaptor probably is the best way to do what you want.

However, it seems that you don’t actually care about the order of the files in the List. Therefore, have you considered changing ClassB so that it takes an unordered collection (like a Set) instead?


A one-liner using argThat which compares the two lists as sets:

verify(mock).method(argThat(list -> new HashSet<>(expected).equals(new HashSet<>(list))));