测试类中的模拟类

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

例如:

我的班级.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());
}

我可以欺骗从中排除不必要的逻辑吗?我可以重写简单返回的方法吗?AnythingPerformerClassAnythingPerformerClassdoSomething()truefalse

为什么我指定Mockito,因为我需要它来测试Robolactric的Android。


答案 1

您可以重构,以便它使用依赖关系注入。与其让它创建一个实例,不如将类的实例传递给构造函数,如下所示:MyClassAnythingPerformerClassMyClass

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);
   ...
}

或者,如果包含状态,则可以将 a 传递给构造函数。AnythingPerformerClassAnythingPerformerClassBuilder


答案 2

就像现在一样(声明和实例化内部的方法,不可能嘲笑仅使用Mockito。AnythingPerformerClassAnythingPerformerClass

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

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

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

或测试错误处理:

when(anythingPerformerClassMock.doSomething()).thenTrow(new NullPointerException());

推荐