25

我如何在正在测试的班级中使用 Mockito 模拟其他班级?

例如:

MyClass.java

class MyClass {
    public boolean performAnything() {
        AnythingPerformerClass clazz = new AnythingPerformerClass();
        return clazz.doSomething();        
    }
}

AnyPerformerClass.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吗?我可以覆盖doSomething()简单返回的方法truefalse

为什么我指定 Mockito,因为我需要它来使用 Robolectric 进行 Android 测试。

4

3 回答 3

25

您可以重构MyClass以便它使用依赖注入AnythingPerformerClass您可以将类的实例传递给构造函数,而不是让它创建一个实例MyClass

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包含状态,那么您可以将 a 传递AnythingPerformerClassBuilder给构造函数。

于 2013-07-19T10:00:06.087 回答
3

就目前而言(AnythingPerformerClass方法内部的声明和实例化,不可能模拟AnythingPerformerClass仅使用的 Mockito。

如果可能,将声明和实例化都AnythingPerformerClass移到类级别:声明类型的实例变量AnythingPerformerClass并由构造函数实例化它。

这样,您可以更轻松地AnythingPerformerClass在测试期间注入模拟,并指定其行为。例如:

when(anythingPerformerClassMock.doSomething()).thenReturn(true);

或测试错误处理:

when(anythingPerformerClassMock.doSomething()).thenTrow(new NullPointerException());
于 2013-07-19T09:58:48.773 回答
0

您可以在 Mockito 中设置要返回的内容。

when(mock.method()).thenReturn(someValue)
于 2013-07-19T09:57:11.883 回答