Reputation: 2028
Mockito.when(metadataDao.getStuff(Mockito.anyInt()).get(Mockito.anyInt()))
.thenReturn(returnedVariable);
I'm getting the following error:
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.LinkedList.checkElementIndex(LinkedList.java:555)
at java.util.LinkedList.get(LinkedList.java:476)
at
Why can't I use the matchers?
Upvotes: 3
Views: 9539
Reputation: 32323
Mockito.anyInt()
works via side-effects; when it passes the value to a real class, it essentially sends 0.
It looks like metadataDao.getStuff
is returning a real LinkedList
, with size 0. Then, you send what amounts to 0
to that real LinkedList
, which calls the real get
method with size 0, and you get the normal error you expect.
You can avoid problems like this by not ever using chained method calls inside Mockito, in other words, never do:
when(obj.methodOne().methodTwo())
Instead, just use one method call. In your example, this might be:
List<MyObj> mockList = Mockito.mock(List.class);
Mockito.when(metadataDao.getStuff(Mockito.anyInt()).thenReturn(mockList);
Mockito.when(mockList.get(Mockito.anyInt())).thenReturn(returnedVariable);
Also note that, as @JeffBowman points out in the comments, you should never be mocking List
when a real List
will do.
Upvotes: 9
Reputation: 81094
While @durron597 has the right analysis, there is a way to configure Mockito to handle your current code, by configuring your mock with Mockito.RETURNS_DEEP_STUBS
. That way getStuff
will automatically return a mock which can be used for chaining.
In both cases, this behavior of "deep" mocking is discouraged by the Mockito team. Just an excerpt from their sermon (found in the link above):
WARNING: This feature should rarely be required for regular clean code! Leave it for legacy code. Mocking a mock to return a mock, to return a mock, (...), to return something meaningful hints at violation of Law of Demeter or mocking a value object (a well known anti-pattern).
Upvotes: 2