使用 Mockito 测试抽象类
2022-08-31 05:38:36
我想测试一个抽象类。当然,我可以手动编写一个从该类继承的模拟。
我可以使用模拟框架(我使用的是Mockito)而不是手工制作我的模拟来做到这一点吗?如何?
我想测试一个抽象类。当然,我可以手动编写一个从该类继承的模拟。
我可以使用模拟框架(我使用的是Mockito)而不是手工制作我的模拟来做到这一点吗?如何?
下面的建议让你测试抽象类而不创建一个“真实”的子类 - Mock是子类。
使用 ,然后模拟调用的任何抽象方法。Mockito.mock(My.class, Mockito.CALLS_REAL_METHODS)
例:
public abstract class My {
public Result methodUnderTest() { ... }
protected abstract void methodIDontCareAbout();
}
public class MyTest {
@Test
public void shouldFailOnNullIdentifiers() {
My my = Mockito.mock(My.class, Mockito.CALLS_REAL_METHODS);
Assert.assertSomething(my.methodUnderTest());
}
}
注意:此解决方案的美妙之处在于,您不必实现抽象方法,只要从不调用它们即可。
老实说,这比使用间谍更整洁,因为间谍需要一个实例,这意味着你必须创建抽象类的可实例化子类。
如果你只需要测试一些具体的方法而不触及任何抽象,你可以使用(参见Morten的答案),但是如果被测试的具体方法调用一些抽象,或者未实现的接口方法,这将不起作用 - Mockito会抱怨“无法在java接口上调用real method”。CALLS_REAL_METHODS
(是的,这是一个糟糕的设计,但有些框架,例如Tapestry 4,有点强迫你。
解决方法是反转这种方法 - 使用普通的模拟行为(即,所有内容都被模拟/存根),并用于显式调用所测试的具体方法。例如:doCallRealMethod()
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();
}
}
更新以添加:
对于非 void 方法,您需要使用 thenCallRealMethod()
代替,例如:
when(myInstance.myNonVoidMethod(someArgument)).thenCallRealMethod();
否则,Mockito会抱怨“检测到未完成的存根”。