我试图了解如何使用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?在这种情况下我需要使用模拟吗?
答案 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进行假设。