Se hai solo bisogno di testare alcuni dei metodi concreti senza toccare nessuno degli abstract, puoi usare CALLS_REAL_METHODS
(vedi la risposta di Morten ), ma se il metodo concreto sotto test chiama alcuni degli abstract, o metodi di interfaccia non implementati, questo non funzionerà - Mockito si lamenterà "Impossibile chiamare il metodo reale sull'interfaccia java".
(Sì, è un design scadente, ma alcuni framework, ad esempio Tapestry 4, ti costringono a forza.)
La soluzione alternativa è quella di invertire questo approccio: utilizzare il normale comportamento simulato (ovvero, tutto è deriso / stub) e utilizzare doCallRealMethod()
per richiamare esplicitamente il metodo concreto sotto test. Per esempio
public abstract class MyClass {
@SomeDependencyInjectionOrSomething
public abstract MyDependency getDependency();
public void myMethod() {
MyDependency dep = getDependency();
dep.doSomething();
}
}
public class MyClassTest {
@Test
public void myMethodDoesSomethingWithDependency() {
MyDependency theDependency = mock(MyDependency.class);
MyClass myInstance = mock(MyClass.class);
// can't do this with CALLS_REAL_METHODS
when(myInstance.getDependency()).thenReturn(theDependency);
doCallRealMethod().when(myInstance).myMethod();
myInstance.myMethod();
verify(theDependency, times(1)).doSomething();
}
}
Aggiornato per aggiungere:
Per i metodi non nulli, dovrai utilizzare thenCallRealMethod()
invece, ad esempio:
when(myInstance.myNonVoidMethod(someArgument)).thenCallRealMethod();
Altrimenti Mockito si lamenterà "Rilevamento di mozziconi incompiuti".
SomeAbstract spy = spy(SomeAbstract.class);