单元测试:(白盒测试时)应涵盖多少?

时间:2018-08-22 11:47:16

标签: 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
            return a + b;
    };
}

进一步假设OffsetProvider::applyOffset()OffsetProvider::getOffset()不必总是返回相同的值({年的applyOffset()false,{ {1}}通常会返回getOffset(),但会在星期一13日产生不同的值。

将此类放在单元测试中(以便您可以对其进行重构),您会很快注意到很难覆盖42路径(但是您可以通过一些技巧来做到)。仔细观察,您还会发现else的结果取决于addWithOffset()的结果。

您的考试涵盖范围是否应包括那些可能的分歧点(即也可以在leap年和周一13日进行模拟考试)?即将进行的重构可能会使这些测试很快过时,但是如果您不进行测试,则可能不会发现自己意外地对getOffset()进行了硬编码,而不是使用42中的值。

1 个答案:

答案 0 :(得分:0)

浏览评论并仔细研究问题,我得出以下结论(至少对我而言):

如果函数调用对被测函数有直接影响(例如,提供返回值),则需要对其进行介绍。例如:

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;
}

您可能想在此处插入ab的一些示例值,但是-老实说-您真正想做的是 mock 计算器: :add(),因此您可以验证indirectAdd()是否同时调用Calculator::add()并使用值Calculator::add()返回。