如何测试调用另一个类的方法的方法?

时间:2018-02-22 00:02:59

标签: java unit-testing mocking

我试图了解如何使用Mockito进行单元测试。 我发现的所有情况都是当A类依赖于B类时,即A具有B类属性。我很清楚这种情况。但是当A使用B而不将其作为属性时,如何进行测试。

假设我有这段代码:

import package.classB;
public class A
{
    public int methodA(classB b) 
    {
    int x= b.methodB();
    //do something with x and then return the result
    }
}

如何测试方法A?在这种情况下我需要使用模拟吗?

1 个答案:

答案 0 :(得分:3)

我怀疑这将成为一场哲学辩论,它可能主要是。

答案是 - 这取决于。

您可以使用Mockito对象,也可以只传入一个完全形成的对象作为参数。两者都有好处和不足之处。

让我们假设ClassB只是一个简单的POJO。像用户记录一样的东西。它有一个userID和一个名称字段,您想测试methodA。我通常只创建一个用户对象的实例,然后将其传递给参数。

您的测试可能看起来像

public class TestA {

   public void testMethodA() {
     B b = new B();
     int expectedValue = 1000;
     A a = new A();
     assertEquals(expectedValue, a.methodA(b));
   }

}

这样做的好处是你有一个完全形成的对象B,你正在使用真实数据进行测试。这样做的缺点是对象B可能非常复杂或需要很长时间才能生成。例如,对象B可以是数据库查找。

如果需要模拟对象B,可以使用Mockito进行模拟,然后您可以使用很多方法来处理它。最简单的情况是上面的变化。

public class TestA {

   public void testMethodA() {
     B b = Mockito.mock(B.class);
     Mockito.when(b.methodB()).thenReturn(10);
     int expectedValue = 1000;
     A a = new A();
     assertEquals(expectedValue, a.methodA(b));
   }
}

这样做的好处是你不必担心对象B中发生了什么。你关心的是对象B中的methodB返回10.你只是测试方法A,它没有关心对象B正在做什么。这可以快得多。缺点是您正在假设对象A正在对对象B执行什么操作。如果对象A确定它需要方法A中的对象B的另一个方法,则您的测试将失败。它也可能隐藏了对象B中的一些实现,这在某些情况下可能会变得很重要。

就个人而言,我倾向于尝试尽可能少地模仿。这使得测试的设置更加复杂,每次测试运行所需的时间更长,但好处是我从根数据开始测试整个过程直到方法A.

但是模拟对象B没有任何问题。测试变得更简单,也可能更快,但是你正在对对象B进行假设。