JUnit 测试抛出异常的错误形式?
我对 JUnit 还很陌生,我真的不知道异常和异常处理的最佳实践是什么.
I'm pretty new to JUnit, and I don't really know what best practices are for exceptions and exception handling.
例如,假设我正在为 IPAddress 类编写测试.它有一个构造函数 IPAddress(String addr),如果 addr 为 null,它将抛出 InvalidIPAddressException.据我通过谷歌搜索得知,空参数的测试将如下所示.
For example, let's say I'm writing tests for an IPAddress class. It has a constructor IPAddress(String addr) that will throw an InvalidIPAddressException if addr is null. As far as I can tell from googling around, the test for the null parameter will look like this.
@Test
public void testNullParameter()
{
try
{
IPAddress addr = new IPAddress(null);
assertTrue(addr.getOctets() == null);
}
catch(InvalidIPAddressException e)
{
return;
}
fail("InvalidIPAddressException not thrown.");
}
在这种情况下,try/catch 是有意义的,因为我知道异常即将到来.
In this case, try/catch makes sense because I know the exception is coming.
但是现在如果我想编写 testValidIPAddress(),有几种方法可以做到:
But now if I want to write testValidIPAddress(), there's a couple of ways to do it:
方式#1:
@Test
public void testValidIPAddress() throws InvalidIPAddressException
{
IPAddress addr = new IPAddress("127.0.0.1");
byte[] octets = addr.getOctets();
assertTrue(octets[0] == 127);
assertTrue(octets[1] == 0);
assertTrue(octets[2] == 0);
assertTrue(octets[3] == 1);
}
方式#2:
@Test
public void testValidIPAddress()
{
try
{
IPAddress addr = new IPAddress("127.0.0.1");
byte[] octets = addr.getOctets();
assertTrue(octets[0] == 127);
assertTrue(octets[1] == 0);
assertTrue(octets[2] == 0);
assertTrue(octets[3] == 1);
}
catch (InvalidIPAddressException e)
{
fail("InvalidIPAddressException: " + e.getMessage());
}
}
标准做法是向 JUnit 抛出意外异常还是自己处理它们?
Is is standard practice to throw unexpected exceptions to JUnit or just deal with them yourself?
感谢您的帮助.
实际上,异常测试的旧风格是在抛出异常的代码周围包裹一个 try 块,然后添加一个 fail() 语句在 try 块的末尾.像这样:
Actually, the old style of exception testing is to wrap a try block around the code that throws the exception and then add a fail()
statement at the end of the try block. Something like this:
public void testNullParameter() {
try {
IPAddress addr = new IPAddress(null);
fail("InvalidIPAddressException not thrown.");
} catch(InvalidIPAddressException e) {
assertNotNull(e.getMessage());
}
}
这和你写的没什么不同,但是:
This isn't much different from what you wrote but:
- 你的
assertTrue(addr.getOctets() == null);
没用. - IMO 的意图和语法更清晰,因此更易于阅读.
不过,这有点难看.但这正是 JUnit 4 的用武之地,因为异常测试是 JUnit 4 中最大的改进之一.使用 JUnit 4,您现在可以像这样编写测试:
Still, this is a bit ugly. But this is where JUnit 4 comes to the rescue as exception testing is one of the biggest improvements in JUnit 4. With JUnit 4, you can now write your test like this:
@Test (expected=InvalidIPAddressException.class)
public void testNullParameter() throws InvalidIPAddressException {
IPAddress addr = new IPAddress(null);
}
很好,不是吗?
现在,关于真正的问题,如果我不希望抛出异常,我肯定会选择方法 #1(因为它不那么冗长)并让 JUnit 处理异常并按预期失败测试.
Now, regarding the real question, if I don't expect an exception to be thrown, I'd definitely go for way #1 (because it's less verbose) and let JUnit handle the exception and fail the test as expected.