JUnit测试抛出异常的错误形式?

2021/01/17 03:22 · java ·  · 0评论

我对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块的末尾添加一条语句。像这样:

public void testNullParameter() {
    try {
        IPAddress addr = new IPAddress(null);
        fail("InvalidIPAddressException not thrown.");
    } catch(InvalidIPAddressException e) {
        assertNotNull(e.getMessage());
    }
}

这与您编写的内容没有太大不同,但:

  1. assertTrue(addr.getOctets() == null);没用。
  2. IMO的意图和语法更加清晰,因此更易于阅读。

尽管如此,这还是有点丑陋。但这就是JUnit 4抢救的地方,因为异常测试是JUnit 4中最大的改进之一。有了JUnit 4,您现在可以像这样编写测试:

@Test (expected=InvalidIPAddressException.class) 
public void testNullParameter() throws InvalidIPAddressException {
    IPAddress addr = new IPAddress(null);
}

很好,不是吗?

现在,关于真正的问题,如果我不希望引发异常,我肯定会选择方法1(因为它不太冗长),并让JUnit处理该异常并按预期通过测试。

对于我不希望发生异常的测试,我不会费心去捕获它。我让JUnit捕获异常(可靠地执行此操作),并且在声明throws原因(如果需要)的情况下根本不满足该异常

我注意到 您的第一个示例,您没有使用@expected注释viz。

@Test (expected=IndexOutOfBoundsException.class) public void elementAt() {
    int[] intArray = new int[10];

    int i = intArray[20]; // Should throw IndexOutOfBoundsException
  }

我将这个用于所有测试抛出异常的测试。它比我必须在Junit3中使用的等效catch / fail模式要简短。

从JUnit 4.7开始,您可以使用ExpectedException规则,应该使用它。该规则使您可以精确定义要在测试代码中引发异常的调用方法。此外,您可以轻松地将字符串与异常的错误消息进行匹配。在您的情况下,代码如下所示:

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    @Test
    public void test() {
        //working code here...
        expectedException.expect(InvalidIPAddressException.class);
        IPAddress addr = new IPAddress(null);
    }

更新:在他的《用JUnit和Mockito进行的实际单元测试》一书中 Tomek Kaczanowski反对使用ExpectedException,因为该规则“破坏了单元测试的安排/动作/声明流程”(他建议使用Catch Exception图书馆)。尽管我能理解他的观点,但我认为如果您不想引入另一个第三方库,则使用该规则很好(使用该规则总比“手动”捕获异常要好)。

对于null测试,您可以简单地执行以下操作:

public void testNullParameter() {
    try {
            IPAddress addr = new IPAddress(null);
            fail("InvalidIPAddressException not thrown.");
    }
    catch(InvalidIPAddressException e) { }
}

如果异常中有一条消息,您也可以根据需要在捕获中检查该消息。例如

String actual = e.getMessage();
assertEquals("Null is not a valid IP Address", actual);

对于有效的测试,您不需要捕获异常。如果引发异常但未捕获异常,则测试将自动失败。因此,方法1将是您所需要的,因为它会失败,并且无论如何您都可以使用堆栈跟踪以获取观看乐趣。

如果我了解您的问题,答案是-个人喜好。

我个人在测试中抛出异常。在我看来,因断言而失败的测试等同于因未捕获的异常而失败的测试。两者都显示需要修复的内容。

在测试中要记住的重要事情是代码覆盖率。

一般而言,方法#1是可行的,没有理由指出因错误而导致的故障-无论哪种方式,测试本质上都是失败的。

如果您需要错误消息的唯一信息,那么第二种方法才有意义,而只有一个例外不会告诉您。然后捕捉和失败可以更好地宣布失败原因。

注册:测试异常

我同意“ Pascal Thivent”,即使用
@Test (expected=InvalidIPAddressException.class)


注册:测试 testValidIPAddress

IPAddress addr = new IPAddress("127.0.0.1");
byte[] octets = addr.getOctets();

我会写一个像

class IPAddressTests
{

    [Test]
    public void getOctets_ForAValidIPAddress_ShouldReturnCorrectOctect()
    {
         // Test code here
    }

}

关键是当testinput为VALID ipAddress时

,测试必须在类的公共方法/功能上声明它们按例外方式工作。

IMO最好处理异常并显示测试中的适当消息,而不是从测试中抛出异常。

本文地址:http://java.askforanswer.com/junitceshipaochuyichangdecuowuxingshi.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!