【问题标题】:Branch coverage without branching - I know sounds weird没有分支的分支覆盖 - 我知道听起来很奇怪
【发布时间】:2020-11-17 18:15:01
【问题描述】:

我有一堆遵循这种模式的验证代码:

bool IsBroken()
{
    var isBroken = Check(..., "error-1")
        | Check(..., "error-2")
        ...
        | Check(..., "error-n");

    if (...)
    {
        isBroken |= Check(..., "error-1")
            | Check(..., "error-2")
            ...
            | Check(..., "error-n");
    }
    else
    {
        isBroken |= Check(..., "error-1")
            | Check(..., "error-2")
            ...
            | Check(..., "error-n");
    }

    // ...
    // Could have more if-else or even nested if-else

    return isBroken;
}

bool Check(bool condition, string message)
{
    if (condition)
    {
        errors.Add(message);
    }
    return condition;
}

目标是执行所有检查,无论结果如何。然而,这段代码的问题在于它对分支覆盖不友好。

一个简单的解决方法是用函数体替换Check(bool, string),但这会产生另一个较小的问题,即代码混乱。我正在尝试找出一个可以让我两全其美的解决方案。有什么想法吗?!

【问题讨论】:

标签: java c# unit-testing testing code-coverage


【解决方案1】:

如果有很多重复验证(if-checks)并且它们很短,您可以创建一个需要完成的检查字典。将此字典传递给方法,迭代字典中的项目并在发生验证错误时添加错误消息。

示例代码:

class A
{
    Dictionary<Func<A, bool>, string> dictOfChecks = new Dictionary<Func<A, bool>, string>()
    {
        //Example of checks                 , Error Message
        { (arg) => arg.ToString().Length < 3, "Length is smaller than 3" },
        { (arg) => arg.ToString().Length < 2, "Length is smaller than 2" },
    };

    public bool IsBroken()
    {
        //there you can enter multiple call of GetErrors to check whether there are some
        var errors = GetErrors(dictOfChecks);

        return errors.Length == 0;
    }

    public string[] GetErrors(Dictionary<Func<A, bool>, string> dict)
    {
        var errors = new List<string>();

        foreach (KeyValuePair<Func<A, bool>, string> kvp in dict)
        {
            if (kvp.Key.Invoke(this))
                errors.Add(kvp.Value);
        }

        return errors.ToArray();
    }
}

【讨论】:

    【解决方案2】:

    想出了一个好的解决方案:

    _ = condition && Append("error");
    
    bool Append(string error)
    {
        errors.Add(error);
        return true;
    }
    

    虽然这也可以写成if (condition) Append("error")。在我们的例子中,块语句必须写成:

    if (condition)
    {
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-15
      • 1970-01-01
      • 2018-05-16
      • 2021-10-01
      • 2011-09-07
      • 2013-11-10
      • 1970-01-01
      • 2012-06-27
      • 2015-02-08
      相关资源
      最近更新 更多