C++ 单元测试:您应该覆盖多少(在白盒测试时)?

C++ 单元测试:您应该覆盖多少(在白盒测试时)?,c++,unit-testing,refactoring,C++,Unit Testing,Refactoring,假设我有以下类别: class WeirdCalculator { public: WeirdCalculator() { }; int addWithOffset(int a, int b) { OffsetProvider provider; if (provider.applyOffset()) return a + b + provider.getOffset(); else

假设我有以下类别:

class WeirdCalculator
{
  public:
    WeirdCalculator() { };

    int addWithOffset(int a, int b)
    {
        OffsetProvider provider;
        if (provider.applyOffset())
            return a + b + provider.getOffset();
        else
            return a + b;
    };
}
进一步假设
OffsetProvider::applyOffset()
OffsetProvider::getOffset()
不必要总是返回相同的值(
applyOffset()
在闰年为
false
,而
getOffset()
通常返回
42
,但在13日星期一产生不同的值)

将这个类置于单元测试之下(这样您就可以重构它),您会很快注意到很难覆盖
else
路径(但是您可以通过一些技巧来实现)。仔细观察,您还注意到
addWithOffset()
的结果取决于
getOffset()
的结果


您的测试覆盖范围是否应包括那些可能的分歧点(即,还应模拟闰年和13日星期一的测试)?即将到来的重构可能会使这些测试很快过时,但如果你不涵盖它们,你可能不会发现你意外地硬编码了
42
,而不是使用
getOffset()

中的值查看注释并仔细考虑这个问题,我得出了以下结论(至少对我来说):

如果函数调用对您的被测函数有直接影响(例如,提供返回值),那么您需要覆盖它。例如:

int indirectIsOdd(int a)
{
    //Please ignore the fact that I could just write "return Calculator::isOdd(a)" here
    if (Calculator::isOdd(a))
        return true;
    else
        return false;
}
很明显,您需要涵盖
Calculator::isOdd()
的两种可能结果,否则就无法涵盖整个代码

int indirectAdd(int a, int b)
{
    int result = Calculator::add(a, b);
    return result;
}

您可能想在这里为
a
b
插入一些示例值,但是——老实说——您真正想要做的是模拟计算器::add(),这样您就可以验证
indirectAdd()
这两个调用
Calculator::add()
并使用值
Calculator::add())
返回。

在测试中,单例测试一直是个难题。这个主题(太?)广泛,而且在网络上得到了很好的处理@YSC我在问我的问题之前看到了这些答案,我不认为重构之前应该涵盖哪些内容的问题已经在副本中得到了回答-但是既然你和Martin Bonner已经结束了这个问题,我就不再为此烦恼了。@CharonX请随意编辑你的问题并解释为什么它不是副本。如果你打我,我可以重新打开它。(请注意,YSC实际上投票决定以“太宽”结束,所以请尽量缩小问题的范围。)@MartinBonner我已经删去了这个问题,并编辑成了一些仍然问我想知道的问题(但以不同的方式问)@CharonX-这样更好。这种简化是值得的,不提及单身汉也会有所帮助。我仍然想知道它是否会因为“过于宽泛”或“主要基于意见”而关闭(你可能也想在QA网站上提问)。