【发布时间】:2019-04-07 18:54:37
【问题描述】:
我有很多类似于以下的类:
public class Foo
{
private readonly Ba _ba;
private Foo(Ba ba)
{
if (ba is null) throw new ArgumentNullException(ba);
_ba = ba;
}
}
在其他类的内部,我将这个构造函数称为Foo,但由于这是意料之外的,所以在每个构造函数中调用ba 不是null。
我为组合框架编写了很多测试方法,但由于上述代码 sn-p 中的异常是较新抛出的,因此我无法达到 100% 的代码覆盖率。
我看到以下替代方案:
-
删除空检查:这适用于当前的项目实现,但每当我可能添加一个意外调用
Foo(null)时,调试会更加困难。 -
用
[ExcludeFromCodeCoverage]装饰构造函数: 这适用于当前的Foo(Ba)实现,但每当我可能更改实现时,构造函数中的新代码路径可能会出现,并且会意外错过测试。
你会如何解决这个难题?
注意事项
代码示例是用 C# 编写的,但问题可能涉及一般的单元测试/异常处理问题。
C# 8 可能会通过introducing non-nullable reference types 解决这个问题,但我正在寻找一个好的解决方案,直到它稳定发布。
【问题讨论】:
-
将构造函数设为
protected,然后继承测试项目中的类,并用这个继承的类运行null测试? -
简单权衡:你有不小心写
new Foo(null)的先例吗?我很确定——没有。然后您提到您编写了很多测试,这意味着每当您将null传递给构造函数时,某些测试将失败,堆栈跟踪指向接收null的类而不是有效依赖项。基于上述删除空检查并享受100%的代码覆盖率和无条件构造函数;) -
为什么不写一个测试来调用这个构造函数并将 null 作为参数传递呢?由于这是一个公共课程,我看不出问题出在哪里。
标签: c# unit-testing testing exception code-coverage