[英]How to unittest the side effects of a method in c++?
在实际的 C++ 项目中,除了返回值和更改输出参数之外,大多数方法都有副作用。
// For examle
bool A::doA()
{
bool isSuccess = true;
isSuccess &= b.doB();
isSuccess &= c.doC();
this->a++;
return isSuccess;
}
上述方法的副作用包括调用2个方法和改变成员变量a。
但是,在为上述方法编写单元测试时,我看到大多数人只是检查返回值而忽略了副作用,这确实达到了 100% 的代码覆盖率。
但我认为这样的单元测试很愚蠢,原因有两个:
1. doA 方法的主要作用是副作用,而不是返回值。
2. 如果 doA 有 void 返回值(这在实际代码中很常见),你甚至不能这样写单元测试。
通过谷歌,我找到了一些测试副作用的方法:
1.mock b 和c,检查doB 和doC 是否被调用。
2.通过一些技术检查成员变量a的值。
但我认为这样的单元测试不好有两个原因:
1.会有这么多的嘲笑和时间成本。 此外,仅检查是否调用了方法似乎很愚蠢。
2.它依赖于方法的实现而不是接口,如果实现改变,单元测试需要改变。 我听到有人说单元测试应该是黑盒测试。
那么在实际项目中如何处理这样的问题呢?
一般来说:
测试总是验证某种可公开观察的行为。 该行为是返回值还是副作用并不重要。 被测代码的 API 和/或文档必须明确说明副作用是什么。 如果副作用没有表现出任何可公开观察到的行为,则它们纯粹是内部实现细节,与测试无关; 它们也不应该是公共 API 或其文档的一部分。
根据经验,不要测试您只知道的事情,因为您查看了被测代码的实现。
关于你的例子:
如果doB()
或doC()
事业相关的副作用,这些都是部分doA()
的观察到的行为。 检查效果本身。 无论他们在那里直接导致doA()
或所谓的内部另一个功能doA()
是一个实现细节,因而无关您的测试。
也许“做 A”的效果是将特定的A
对象添加到注册表中。 那么正确的做法是检查对象是否已注册。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.