Mockito:嘲弄成员变量

时间:2016-03-07 21:20:08

标签: java unit-testing mockito

我有以下代码:

public class ABC {

private double a;
Other_object other_object;

public ABC(int a, int[] b){
    this.a=a;
    other_object=new Other_object(b);
}
...
public int method_1(){
    return other_object.other_method();
}

public int method_2(){
    if(method_1()>0 && a>0)
        return 1;
    else 
        return 0;
}

}

我创建了以下模拟对象: ABC a=mock(ABC.class); Mockito.when(a.method1()).thenReturn(0);

我无法为“int a”设置值。 我试图在ABC中创建一个setter函数,然后嘲笑它,但它不起作用。 我想知道为什么模拟setter函数不起作用我怎么能模拟这个值(int a)?

2 个答案:

答案 0 :(得分:2)

模拟是一个" 假装"做某事。所以关于模拟的重要一点是它的行为,而不是它的状态(因为它并没有真正具有很多状态)。当然你可以让模拟对setter做出反应,存储值然后通过getter返回它,例如通过Answer(我不会提供代码),但我几乎可以保证这不会是一个好的解决您遇到的任何问题。

当您实际上不需要真实对象但想要测试依赖于它的另一个对象时,模拟就是这样。所以你的模拟对象只是一种测试其他东西的方法。

例如,我们假设您正在测试您的班级MyClass。有这样的方法......

public int doSomething(ABC abc) {
    return abc.method_1 * 2;
}

如果你不想使用真正的" ABC"无论出于何种原因,你可以嘲笑它。你对MyClass的测试看起来像这样(浓缩)......

@Test
public void doSomething_must_return_2_when_method_1_returns_1() {
   ABC abcMock = Mockito.mock(ABC.class);
   when(abcMock.method_1()).thenReturn(1);
   Assert.assertEquals(2, myClass.doSomething(abcMock) );
}

如果您确实需要在模拟中存储一些值,那么您要么不需要模拟,要么您的测试用例非常复杂。记住:测试应测试一件事。它应该只有一点失败。如果您有多个测试用例,请使用多个方法,而不是一个方法。如果您的对象需要做的不仅仅是基本的"调用方法,请给出结果"模拟可能不是正确的工具。

但是在你的例子中,你的a对于任何ABC实例都是常量。您在构造函数中初始化它。因此,对于您创建的任何模拟,您的a也是不变的。所以,如果你需要模拟method_2,那么你也已经知道了结果......不需要在任何地方设置。如果你想模拟ABC,你已经知道了,因此知道这些方法会在真正的ABC上返回什么。不需要模拟实际存储并实际使用它。

编辑:如果您要测试method_2(),那么您要测试的是ABC类本身。然后创建一个类ABC的模拟是没有意义的,因为你要测试的就是这个"假的" ABC,但不是真正的ABC,所以你最终会像以前一样聪明,没有关于ABC的知识。所以,如果你想测试你的ABC.method_2(),那么创建一个ABC的实际实例......

ABC abcToTest = new ABC(...);
Assert.assertEquals(..., abcToTest.method_2());

这里不需要(或机会)嘲笑。

答案 1 :(得分:0)

希望下面的代码对您有用

@Mock 
SampleClass sampleClass;

ReflectionTestUtils.setField(sampleClass, "variableName","ISO-8859-1");