阴性测试——我应该期待确切的例外吗
本文关键字:期待 测试 我应该 | 更新日期: 2023-09-27 18:29:12
考虑以下方法
public void Foo(string str)
{
if (str == null)
throw new ArgumentNullException("str");
if (str.Length != 5)
throw new MyException();
}
假设我想为它写一个阴性测试,如下所示:
public void TestFoo()
{
try
{
Foo(null); //this could be an remote call (e.g. WCF)
Assert.Fail("Expected ArgumentNullException");
}
catch (ArgumentNullException) {} //should this be "Exception" instead?
try
{
Foo("four"); //this could be an remote call (e.g. WCF)
Assert.Fail("Expected MyException");
}
catch (MyException) {} //should this be "Exception" instead?
}
在我看来,捕捉如上所述的特定异常是一个实现细节,这可能会使测试变得脆弱,并且与实现(而不是接口)过于耦合。显然,MyException
有一天可能会发生变化,但即使是ArgumentNullException
也可能被包裹在其他异常中(例如,由未来的WCF行为)。通常,测试知道"四"应该失败,这就是它所关心的全部——失败。
例外情况(并非双关语)可能是将异常转换为传递给用户的内容,例如用户友好的消息(例如,映射到用户名的UserNameTakenException
,请尝试其他)。在这种情况下,您需要确保传达了正确的错误。即便如此,这也有点问题,因为这意味着每一个可能的用户错误都会出现不同类型的异常,但这可能还不算太糟(通常情况下不会太多)。
我的思路有道理吗?在不涉及面向用户的异常的测试用例中,我真的应该捕捉到通用的Exception
吗?
只需编写至少4个测试:
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void TestFooForNull()
{
Foo(null);
}
[Test]
[ExpectedException(typeof(MyException))]
public void TestFooForInvalidSizeTooShort()
{
Foo("1234");
}
[Test]
[ExpectedException(typeof(MyException))]
public void TestFooForInvalidSizeTooLong()
{
Foo("123456");
}
[Test]
public void TestFoo()
{
Foo("12345");
}
在编写单元测试时,最好每个测试处理一个特定的案例。
> should I expect the exact exception?
> ...
> Should I indeed catch the generic Exception in test cases that
> don't involve user-facing exceptions ?
在dotnet中,捕获泛型Exception
不是一个好主意,因为这也会捕获AssertionException。我想java也是一样的,
public void ThisTestWillNeverFail()
{
try
{
Assert.Fail("some error message");
}
catch (Exception)
{
}
}