I'm running through some service tests and I am testing a concrete class that extends from one that uses generics.
An example setup of the service layer is below:
public abstract class AbstractService <E extends AbstractEntity, IT extends AbstractItem> {
public void deleteAllItems(E entity) {
List<IT> items = new ArrayList<IT>(entity.getItems());
for(IT item : items) {
//Yada, yada
}
}
}
public class Service extends AbstractService<Entity, Item> {
}
public class OtherService() {
@Inject
private ServiceManager serviceManager;
public void deleteItems(Entity e) {
serviceManager.getService().deleteAllItems(e);
}
}
Then to test it I have the following:
public class Test {
private Service service;
private OtherService otherService;
private ServiceManager serviceManager;
@BeforeMethod
public void setup() {
serviceManager= mock(serviceManager.class);
service= mock(Service.class);
when(serviceManager.getService()).thenReturn(service);
otherService=injector.getInstance(OtherService.class);
}
@Test
public void test() {
Entity e = new Entity();
//Attach some items
otherService.deleteItems(e);
verify(service).deleteAllItems(e);
}
}
This should call the OtherService
, which exists (We're using injection to get ahold of the object), and then call the method deleteItems()
, which in turn should call deleteAllItems()
on the Service
. Before I had implemented the Java generics, this worked fine, but since I have implemented the Java generics, the Mockito test fails with the following exception:
java.lang.NoSuchMethodError: Service.deleteAllItems(Entity;)V at Test.test(Test.java:XXX) org.mockito.exceptions.misusing.UnfinishedVerificationException: Missing method call for verify(mock) here: -> at Test.test(Test.java:XXX)
Example of correct verification: verify(mock).doSomething()
Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified.
Which sounds like it can't find the method. Should I instead mock the abstract class of AbstractService
or is there something else that I am missing?
EDIT
From what I've seen of the Mockito inner workings, it creates an instance of this:
public void AbstractService.deleteAllItems(Entity)
For the MockitoMethod
object, so that would make sense that Service.deleteAllItems()
"isn't called", it appears Mockito assumes only the baseclass was ever called. So it does appear that I need to mock the base class instead. I'm going to investigate further, but if anyone has any other ideas, I'm open to suggestions