Jika Anda hanya perlu menguji beberapa metode konkret tanpa menyentuh abstrak apa pun, Anda dapat menggunakan CALLS_REAL_METHODS
(lihat jawaban Morten ), tetapi jika metode konkret yang diuji memanggil beberapa abstrak, atau metode antarmuka yang tidak diterapkan, ini tidak akan berfungsi - Mockito akan mengeluh "Tidak dapat memanggil metode nyata di antarmuka java."
(Ya, ini desain yang buruk, tetapi beberapa kerangka kerja, misalnya Tapestry 4, semacam memaksakannya pada Anda.)
Solusinya adalah membalikkan pendekatan ini - gunakan perilaku mengejek biasa (yaitu, semuanya diejek / di-stub) dan gunakan doCallRealMethod()
untuk secara eksplisit memanggil metode konkret yang sedang diuji. Misalnya
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();
}
}
Diperbarui untuk menambahkan:
Untuk metode non-void, Anda harus menggunakan thenCallRealMethod()
, misalnya:
when(myInstance.myNonVoidMethod(someArgument)).thenCallRealMethod();
Kalau tidak, Mockito akan mengeluh "Kegagalan yang belum selesai terdeteksi."
SomeAbstract spy = spy(SomeAbstract.class);