javaunit-testingmockitostubbingargument-matcher

Mockito doesn't correctly stub methods taking list as argument


I am trying to mock a class and return a stubbed list of objects when a method on the mocked object is called. Lets consider following code :

interface MyRepositry{
       public List<MyClass> getMyClassInstances(String str,Long id,List<Integer> statusList);
}

I am mocking above method ivocation as follows :

when(myRepository.getMyClassInstances("1234", 200L, stubbedList)).thenReturn(stubbedMyClassInstanceList);

where

 stubbedList 

is the list I create by inserting two integers 1 and 3. In real call also I pass the list I construct which has integers 1 and 3. Point ot note here is stubbedList object and the list object in real call are different but always contain two integers 1 and 3.

stubbedMyClassInstanceList    

is the stubbed list of MyClass instances.

However mockito return an empty list when i run the test. I did some debugging and I guess mockito is not able to match the list object that I am using in

      when(..).thenReturn(..)

call and in actual call and hence doesn't find the correct signature.

I cannot use

anyList() 

matcher as I always pass list of two integers (1 and 3).

I have resolved the problem by using custom

     ArgumentMatcher 

as follows :

     class StatusMatcher extends ArgumentMatcher<List> {
    public boolean matches(Object list) {
        List statuses = ((List) list);
        return (statuses.size() == 2 && statuses.contains(1) && statuses.contains(3));
    }
}

So the question is :

1) Is my guess about why the stubbing/mocking not working correct? 2) and is the solution I have used correct?


Solution

  • Mockito naturally uses equals() for argument matching. The equals() method in List<T> specifies that two lists are defined to be equal if they contain the same elements in the same order.

    Your custom argument matcher, that you say works, is not considering order.

    So maybe the 1 and 3 are in the wrong order in the List<T>?