在C#
中,您可以像这样捕获默认测试套件中的异常:
[TestMethod]
[ExpectedException(typeof (ArgumentNullException))]
public void TestNullComposite()
{
IApi api = new Api();
api.GetDataUsingDataContract(null); // this method throws ArgumentNullException
}
但是当你分析代码覆盖率时,它说你只得到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);
}
但这似乎是毫无理由的额外工作。我建议您重新评估您的测试实践。
在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"));
}
由于该方法本身不会抛出,因此您的覆盖率将是100%。
MAV说的是真的。另外,有一种方法可以将测试类从代码覆盖中排除。
只要用属性[ExcludeFromCodeCoverage]装饰你的[TestClass] !
这样至少在理论上可以达到100% CC
是的,你可以,但首先你必须明白,当
-
期望的异常与你的函数抛出的异常匹配如
assertThrows (NullPointerException.class()→userProfileService.getUserDetailById (userProfile.getAssociateId ()));
-
当预期异常和实际异常不匹配或assertthrow没有抛出任何异常时。考虑上面的场景示例,假设被调用的函数将抛出除NullPointerException之外的其他异常,那么assertthrow将失败。
现在你必须同时考虑assertthrow的失败和通过。
我找到的解是
userProfile = new UserProfile("101", "Amit Kumar Gupta", "amit@gmail.com", "Software Intern", "No",
"999999999");
userProfile2 = new UserProfile("102", "Satyam Sharma", "Satyam@gmail.com", "Software Engineer", "Yes",
"8769356421");
Mockito.when(userProfileDAO.findById(Mockito.anyString())).thenReturn(Optional.ofNullable(userProfile))
.thenReturn(Optional.ofNullable(userProfile2));
List<Class<? extends Exception>> exceptionClassList = new ArrayList<Class<? extends Exception>>();
exceptionClassList.add(NullPointerException.class);
exceptionClassList.add(IllegalArgumentException.class);
for (int i = 0; i < 2; i++) {
try {
assertThrows(exceptionClassList.get(i),
() -> userProfileService.getUserDetailById(userProfile.getAssociateId()));
} catch (AssertionError e) {
assertNotNull(e.getMessage());
}
}
在这种情况下,Mockito将返回两个值,这两个值都将被assertThrow中的函数调用使用,第一次assertThrow将匹配预期的异常,即NullPointerException.class
第二次assertThrow将失败,因为lambda函数不会抛出任何异常,但assertThrow预计会抛出一个IllegalArgumentException。
它生成AssertionError,因此将被catch块捕获。
现在你有100%的覆盖率