我正在寻找一种方法来测试处理数据的类中的数据,然后以尽可能干净和便携的方式上传数据。因此,我不想诉诸于公开获取函数,以避免任何能够访问此数据。为了保持便携性,我想避免使用测试数据库,以便在任何情况下都可以运行这些测试。
Class Foo {
private int a;
private int b;
private int c;
private DBSaver dbSaver;
public Foo(DBSaver dbSaver) {
this.dbSaver = dbSaver;
}
public void processData() {
processData();
saveToDB();
}
private void workNumbers() {
a = 1;
b = 2;
c = a + b;
}
private void saveToDB() {
List<Integer> list = new ArrayList<>();
list.add(a); list.add(b); list.add(c);
dbSaver.save(list);
}
}
测试类:
class FooTest {
@Mock
DBSaver dbSaver;
@Mock
Foo foo;
@Test
private void test() {when(dbSaver.save(any(ArrayList<>.class))).then(returnsFirstArg());
foo = new Foo(dbSaver);
Mockito.doThrow(new Exception() {
//Now I would like to get a, b and c so I can ensure that they have the proper values.
}
).when(foo).processData();
}
}
Here是代码的pastebin版本]()。
workNumbers()将正常执行,并且由于save()函数已被模拟为什么都不做,因此该代码不会做太严重的事情。
我想问一下现在是否有办法通过模拟抛出的异常,以列表形式返回a,b和c值。问题是通过FooTest中的模拟实例访问Foo中的私有值。
答案 0 :(得分:1)
您正在通过模拟错误进行单元测试。有这个没有意义:
@Mock
Foo foo;
Foo是你的“被测试的课程”。你做不想要嘲笑它。如果有的话,您可能需要在此处创建间谍,以便执行 partial mocking 。
在您的情况下,您无需访问这些私人字段。你知道,关键是你的代码会调用:
dbSaver.save(list);
在某个时候。含义:您可以使用Mockitoy 验证在模拟 dbSaver对象上调用save()
时传递特定列表。
这就是重点:你有那个模拟的dbSaver实例,所以你在 total 控制那里发生了什么。如上所述,您可以验证使用特定参数调用其方法;或者您甚至可以使用ArgumentCaptor来访问传递给该方法调用的列表。
然后,您只需确保该列表包含预期的内容(这将是您所测试的类中的三个值!)。看到 here例如如何做到这一点。
最后:尤其是“异常”部分确实是错误的。这里不需要生成异常。您只需将模拟的dbSaver推送到Foo的实例中,就可以在该Foo实例上调用方法;然后你检查预期的结果。而已;其他任何东西都是(无用的)过度复杂的东西。