繁体   English   中英

如何在 C++ 中对方法的副作用进行单元测试?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM