在单元测试中抛出异常时,如何获得100%的覆盖率?

ste*_*hen 4 c# unit-testing

C#你能赶上在默认的测试套件像这样的例外:

[TestMethod]
[ExpectedException(typeof (ArgumentNullException))]
public void TestNullComposite()
{
    IApi api = new Api();
    api.GetDataUsingDataContract(null); // this method throws ArgumentNullException
}
Run Code Online (Sandbox Code Playgroud)

但是,当您分析代码覆盖率时,它表示您只获得66.67%的覆盖率,因为最后一个大括号未被覆盖.

我如何才能在单元测试中实现100%的覆盖率?

MAV*_*MAV 6

通常,当人们测量代码覆盖率时,他们会查看测试所涵盖的代码而不是测试本身.

如本案例所示,要求对测试单元进行100%覆盖是没有意义的.

该测试应该抛出.这就是你正在测试的.

如果你真的想要执行整个方法,我想你可以测试是否手动抛出异常.像这样的东西(没有测试它,但我不明白为什么它不应该工作):

[TestMethod]
public void TestNullComposite()
{
    IApi api = new Api();
    bool didThrow = false;
    try
    {
        api.GetDataUsingDataContract(null); // this method throws ArgumentNullException
    }
    catch(ArgumentNullException) 
    {
        didThrow = true;
    }
    Assert.IsTrue(didThrow);
}
Run Code Online (Sandbox Code Playgroud)

但似乎没有充分理由的额外工作.我建议你重新评估你的测试实践.

  • 您的测试不需要100%.你已经没事了. (2认同)

Oli*_*ver 4

在NUnit中,您有一个方法Assert.Throws<Exception>(),它检查是否抛出了所需的异常。它还返回该异常作为返回值,以便您可以根据需要进行进一步的断言:

[Test]
public void Api_GetDataUsingDataContractWithNullParameter_ThrowsArgumentNullException()
{
    var api = new Api();
    var exception = Assert.Throws<ArgumentNullException>(() => api.GetDataUsingDataContract(null));
    Assert.That(exception.Message, Is.Not.Null.Or.Empty);
    Assert.That(exception.Message, Is.StringContaining("source"));
}
Run Code Online (Sandbox Code Playgroud)

由于该方法本身不会抛出异常,因此您的覆盖率将是 100%。