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?
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>
?