在嵌套函数调用的场景中,模拟测试有一个严重的概念问题。我在我的项目中使用JUnit和Mockito。让我用下面的例子来解释我的问题:-
public class ClassA {
public void methodOne(param1, param2, param3, param4) {
// do something
String temp = methodTwo(param2, param3, param4);
// do something
}
public String methodTwo(param2, param3, param4) {
// do something
return methodThree(param2, param3) + methodFour(param4);
}
public String methodThree(param2, param3) {
// do something
return param2.get(0).getIndex + ":" + param3.getPosition();
}
public String methodFour(param4) {
// do something
return param4.getDetail() + "|" + param4.getCount();
}
}
如果我们必须测试像methodThree()
和methodFour()
这样的基本方法,我们可以创建具有所需存根的所需参数的mock(以支持正在测试的函数的执行),然后执行和验证(状态/行为)。
但是像methodTwo()
这样的方法呢?它嵌套了对其他函数的调用,这些函数已经作为一个单独的单元进行了测试。如果我们将mock对象传递到methodTwo()
中,它们将被传递到嵌套方法中,并将给出NullPointerException()
,因为这些mock没有根据嵌套函数调用的需要进行存根处理。当然,我们也可以在mock中添加额外的存根,以支持嵌套调用中的平稳执行,但显然这不是一种健康的方法。随着我们转向像methodOne()
或其他一些大型方法,这种存根的负担将进一步加重。
就单元测试而言,除了正在测试的单元之外,我们不关心其他单元。请指导我哪里错了,并建议一种更好/正确的单元和模拟测试方法。谢谢
我的想法是,methodOne
和methodTwo
在它们应该具有的行为方面都符合某种规范。事实上,您选择通过调用同一类的其他方法来实现其中的每一个方法是无关紧要的;你应该测试他们的行为是否正确。因此,在编写测试时不要看实现,而是要看规范。
当然,如果你选择忽略我的建议,你可以随时使用Mockito间谍,在测试其他方法时找出一些方法。但说真的,不要。