如何使用Mockito模拟正在测试的类中的其他类?
例如:
MyClass.java
class MyClass {
public boolean performAnything() {
AnythingPerformerClass clazz = new AnythingPerformerClass();
return clazz.doSomething();
}
}
AnythingPerformerClass.java
class AnythingPerformerClass {
public boolean doSomething() {
//very very complex logic
return result;
}
}
测试:
@Test
public void testPerformAnything() throws Exception {
MyClass clazz = new MyClass();
Assert.assertTrue(clazz.performAnything());
}
我可以欺骗AnythingPerformerClass
从AnythingPerformerClass
中排除不必要的逻辑吗?我可以为简单返回true
或false
重写doSomething()
方法吗?
为什么我指定Mockito,因为我需要它来进行Robolectric的Android测试。
您可以重构MyClass
,使其使用依赖项注入。您可以将类的一个实例传递给MyClass
的构造函数,而不是让它创建一个AnythingPerformerClass
实例,如下所示:
class MyClass {
private final AnythingPerformerClass clazz;
MyClass(AnythingPerformerClass clazz) {
this.clazz = clazz;
}
public boolean performAnything() {
return clazz.doSomething();
}
}
然后,您可以在单元测试中传递模拟实现
@Test
public void testPerformAnything() throws Exception {
AnythingPerformerClass mockedPerformer = Mockito.mock(AnythingPerformerClass.class);
MyClass clazz = new MyClass(mockedPerformer);
...
}
或者,如果AnythingPerformerClass
包含状态,则可以将AnythingPerformerClassBuilder
传递给构造函数。
按照目前的情况(方法中AnythingPerformerClass
的声明和实例化,不可能仅使用Mockito来模拟AnythingPerformerClass
。
如果可能的话,将AnythingPerformerClass
的声明和实例化都移动到类级别:声明类型为AnythingPerformerClass
的实例变量,并由构造函数对其进行实例化。
这样,您就可以更容易地在测试期间注入AnythingPerformerClass
的mock,并指定其行为。例如:
when(anythingPerformerClassMock.doSomething()).thenReturn(true);
或测试错误处理:
when(anythingPerformerClassMock.doSomething()).thenTrow(new NullPointerException());
您可以在Mockito中设置返回内容。
when(mock.method()).thenReturn(someValue)