I have following structure:
class Sample {
private Map<String A> serviceMap;
@Autowired
private List<A> services;
@PostConstruct
public void init() {
this.serviceMap = this.services.stream().collect(Collectors.toMap(A::getName, s -> s));
}
public void doSomething() {
// Some logic, and gets the serviceName
this.serviceMap.get(serviceName).process(...);
}
}
Now how to test this doSomething method of Sample class. I don't want to call the process method of Abstract class A.
I tried to MockBean the services but the problem is how to use doNothing when for this line this.serviceMap.get(serviceName).process(...);.
You can add a getter function for serviceMap
. The getter will be package-private for testing purposes.
class Sample {
private Map<String A> serviceMap;
@Autowired
private List<A> services;
@PostConstruct
public void init {
this.serviceMap = this.services.stream().collect(Collectors.toMap(A::getName, s -> s));
}
public void doSomething {
// Some logic, and gets the serviceName
getServiceMap().get(serviceName).process(...);
}
Map<String A> getServiceMap(){
return this.serviceMap;
}
}
Then in your test -
//Given
var sampleSpy = spy(Sample.class);
var serviceMapMock = mock(Map.class);
var serviceAMock = mock(A.class);
when(sampleSpy.getServiceMap()).thenReturn(serviceMapMock);
when(serviceMapMock.get(any())).thenReturn(serviceAMock);
doNothing().when(serviceAMock).process();
//When
sample.doSomething();
//Then
//assertions