我对JUnit还是很陌生,我真的不知道对于异常和异常处理有什么最佳实践。
例如,假设我正在为IPAddress类编写测试。它具有一个构造函数IPAddress(String addr),如果addr为null,则将抛出InvalidIPAddressException。据我可以从谷歌搜索中得知,对null参数的测试将如下所示。
@Test public void testNullParameter() { try { IPAddress addr = new IPAddress(null); assertTrue(addr.getOctets() == null); } catch(InvalidIPAddressException e) { return; } fail("InvalidIPAddressException not thrown."); }
在这种情况下,try / catch很有意义,因为我知道异常即将到来。
但是现在,如果我想编写testValidIPAddress(),有两种方法可以做到:
方式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抛出意外的异常还是自己处理?
谢谢您的帮助。
实际上, 异常测试 的旧样式是将try块包装在引发异常的代码周围,然后fail()在try块的末尾添加一条语句。像这样:
fail()
public void testNullParameter() { try { IPAddress addr = new IPAddress(null); fail("InvalidIPAddressException not thrown."); } catch(InvalidIPAddressException e) { assertNotNull(e.getMessage()); } }
这与您编写的内容没有太大不同,但:
assertTrue(addr.getOctets() == null);
尽管如此,这还是有点丑陋。但这就是JUnit 4抢救的地方,因为异常测试是JUnit 4中最大的改进之一。有了JUnit 4,您现在可以像这样编写测试:
@Test (expected=InvalidIPAddressException.class) public void testNullParameter() throws InvalidIPAddressException { IPAddress addr = new IPAddress(null); }
很好,不是吗?
现在,关于真正的问题,如果我不希望引发异常,我肯定会选择方法1(因为它不太冗长),并让JUnit处理该异常并按预期通过测试。