在为函数编写单元测试时,我应该模拟所做的内部函数调用吗?

While writting unittests for a function, should I mock the internal function calls made?

本文关键字:内部 函数调用 模拟 我应该 函数 单元测试      更新时间:2023-10-16
struct api {
void do_yo() {
a = func1();
if (a) dosomething();
func2();
dosomething2();
}
};

现在我正在为do_yo编写单元测试,所以我应该嘲笑func1func2吗?

或者只是测试do_yo的可观察效果?

是的,你需要模拟func1()func2(),看看do_yo()对他们的不同随机行为的反应。

最好func1()do_yo()的影响最大,因此您需要定义a的可能值,这些值将使do_yo()失败或成功。

归根结底,单元测试的目的是消除基于一组未知输入的未定义或零星行为。(即具有更高的代码覆盖率(。


更新

如果函数依赖于外部因素,则模拟所有可能的行为具有挑战性,并且肯定需要时间。因此,我们有一句谚语:"你能控制什么,什么有意义,就嘲笑他们"。

这实际上更像是一个概念性问题。

简单的答案是:嘲笑应该被视为最后的手段。您只在必要时使用它。意思是:没有其他方法可以在不使用模拟的情况下充分测试被测代码。

因此:当你能够在不使用模拟的情况下为do_yo()编写好的单元测试时,那就去做吧。但是,如果您真的需要控制此类内部方法调用,那么您可能无法绕过嘲笑它们。

这实际上是关于平衡不同的要求/实践。

这有点难以分辨,因为没有足够的关于func1func2的信息,但如果它们像你说的那样是公开的,那么我会嘲笑他们。

如果它们是公开的,那么无论测试do_yo如何,您也应该对它们进行单元测试,这样您就可以证明它们的逻辑符合您的预期。

(把它想象成一家餐厅的试运行:如果你测试厨师可以准备饭菜以满足你的期望,现在你想测试服务员从厨房拿饭菜,你所需要的只是厨房工作人员的回应"饭菜准备好了"或任何其他你可能期望的回应,而不是真正的饭菜。

正如一些人所提到的,如果func1func2正在打击一些外部因素,那么这将成为一种集成测试,而不是嘲笑他们。