在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%的覆盖率?
通常,当人们测量代码覆盖率时,他们会查看测试所涵盖的代码而不是测试本身.
如本案例所示,要求对测试单元进行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)
但似乎没有充分理由的额外工作.我建议你重新评估你的测试实践.
在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%。