Reputation: 10127
So we have this method here that is accessible by the rest of the system which calls underlying methods according to the input.
public SomeReturnObj doSomethingWithInputs(List<Input> inputs) {
for(Input input : inputs) {
if(input.getName().equals("A") {
handleAInput(input);
}
else if(input.getName().equals("B") {
handleBInput(input);
}
else { ... }
}
// ...
}
To get a good code coverage, I would like to test, that if I put a list with two Inputs
with name A
and three with name B
, the corresponding internal methods are called twice or three times, respectively.
So I've tried the following:
@Test
public void separatingInputsByName() {
Input entry1 = mock(Input .class);
Input entry2 = mock(Input .class);
Input entry3 = mock(Input .class);
doReturn("A").when(entry1).getName();
doReturn("A").when(entry2).getName();
doReturn("B").when(entry3).getName();
ClassUnderTest sut = mock(ClassUnderTest .class);
sut.doSomethingWithInputs(Arrays.asList(entry1, entry2, entry3));
verify(sut).handleAInput(entry1);
verify(sut).handleAInput(entry2);
verify(sut).handleBInput(entry3);
}
Unfortunately this does not lead to a proper invocation of the internal methods, probably because the class under test is mocked, so the method implementation is different.
How can I test/verify a method like this properly?
Upvotes: 0
Views: 288
Reputation: 121730
You should use spy()
, not mock()
.
When you use mock()
, all methods are "overriden" so that default actions are taken instead of calling the real methods; spy()
will simply register method invocations.
Therefore:
ClassUnderTest sut = spy(new ClassUnderTest(...));
sut.doSomethingWithInputs(Arrays.asList(entry1, entry2, entry3));
verify(sut).handleAInput(entry1);
verify(sut).handleAInput(entry2);
verify(sut).handleBInput(entry3);
verifyNoMoreInteractions(sut); // if necessary
Also, you can:
when(entry1.getName()).thenReturn("A");
Personally, I find it easier to read, but that's a matter of taste, of course.
Also, you can use InOrder
in your case:
final InOrder inOrder = inOrder(sut);
inOrder.verify(sut).handleAInput(entry1);
// etc
Upvotes: 1