I'm fairly new to Mocking, but I've read a lot, also took a course in udemy (not like I'm an expert, very far from it, just saying I've been studying this), but still, I cannot figure out something.
I have read this post Mockito - difference between doReturn() and when(), which made me understand a few things.
Now let me explain my problem.
I have a service impl class, that calls a repository class to get/do whatever I want. This service class is the one I'm writing my mockito's tests for.
This problem can be addressed in 2 different ways.
First way: (when thenReturn)
I have my test class which looks something like this (pseudo code):
serviceImplCastTest {
@Spy
@InjectMocks
ServiceImplClass serviceImplClass;
@Mock
RepositoryClass repositoryClass;
@Test
void whenMethodInService_thenReturnNonEmptyMap() {
List<Class> classList = new ArrayList<~>();
Class class = new Class("Whatever");
classList.Add(class)
Map<String, Class> classMap = classList.stream.collect(Collectors.toMap(Class::getMethod, Function.identity()));
when(serviceImplClass.methodInService()).thenReturn(classMap);
Map<String, Class> actualMap = serviceImplClass.methodInService();
assertFalse(actualMap.isEmpty());
verify(repositoryClass, times(1)).methodInRepository();
}
So, this doesn't work because the method in the service, which returns a map, calls a method in the repository that returns a List of Class and then my method in the service turns that list into a map, and for some reason, Mockito is expecting a List of Class, instead of a Map. I get the Mockito wrong type of return error.
(This code works perfectly if the service method just returns the same type of List that the repository returns.)
Second way: (doReturn when)
serviceImplCastTest {
@Spy
@InjectMocks
ServiceImplClass serviceImplClass;
@Mock
RepositoryClass repositoryClass;
@Test
void whenMethodInService_thenReturnNonEmptyMap() {
List<Class> classList = new ArrayList<~>();
Class class = new Class("Whatever");
classList.Add(class)
Map<String, Class> classMap = classList.stream.collect(Collectors.toMap(Class::getMethod, Function.identity()));
doReturn(classMap).when(serviceImplClass).methodInService();
Map<String, Class> actualMap = serviceImplClass.methodInService();
assertFalse(actualMap.isEmpty());
verify(repositoryClass, times(1)).methodInRepository();
}
Now, when using doReturn when, everything works fine, except the verify, repositoryClass.methodInRepository() doesn't get called, or at least is not spied properly or something, Mockito throws error "Wanted but not invoked".
So I'm not sure how to fix this on the Mockito side, because a simple way is to change logic, service return list instead of map, then change my application to receive list and map it over there, but this implies affecting logic, which I was forbidden to do so.
Also and I'm honestly interested on being able to mock this, because I have a few other equivalent cases, where my service class processes the list then turns it into something else, and mocking still expects a list to be returned.
How can I mock this? What is the correct approach?