有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

测试引发异常的方法时的java验证行为

最近,在一次代码审查中,一位同事说“测试不应该有try-catch块”。他还向我指出了关于^{}的信息,我能够用它重写一些对异常数据进行检查的测试

然而,我遇到了一种情况,我不确定我是否可以消除尝试捕捉。我正在为一个方法编写一个单元测试,该方法将抛出一个异常,该异常将执行我需要使用JMockit验证的一些行为。假设测试代码包含以下内容

try {
    ...code...
} catch (SomeException e) {
    statusMessage.send("Failure", <parameters with some data>);
    throw e;
}

JUnit测试目前看起来像

@Test
public void test() {
    ... set things up ...
    try {
        callTheMethod();
        fail("No exception thrown");
    } catch (Exception e) {
        assertEquals(SomeException.class, e.getClass());
    }
    new Verifications() { {
        statusMessage.send("Failure", <expected data>);
    } }
}

我找不到一个好办法来摆脱这种尝试。就我个人而言,我不认为把它放在那里有什么问题,但如果我至少不尝试摆脱它,我可能会从我的同事那里得到的教训:):)

不需要failassertEquals。如果有一种简单的方法告诉JUnit/JMockit忽略来自callTheMethod()的任何异常并继续,那就好了——我可以创建另一个测试来检查异常

有什么JUnit或JMockit特性可以让我完成我想要做的事情吗

[注意:经过编辑以明确我正在测试的行为是对模拟对象的调用,而不是静态方法调用。这与问题无关。]


共 (4) 个答案

  1. # 1 楼答案

    目前,如果要在抛出断言后验证某些内容,使用纯JUnit时必须使用try-catch。有了JUnit 4.13(尚未发布),您可以使用

    expectThrows(Exception.class, () -> callTheMethod());
    new Verifications() { {
        statusMessage.send("Failure", <expected data>);
    } }
    

    作为替代,您可以使用Fishbowl's ignoreException

    ignoreException(() -> callTheMethod());
    new Verifications() { {
        statusMessage.send("Failure", <expected data>);
    } }
    

    充分披露:我是《鱼缸》的作者

  2. # 2 楼答案

    基于API,我想说你可以做如下事情:

    class AjbUnitTest
    {
        @Rule 
        public ExpectedException thrown = ExpectedException.none();
    
        @Test
        public void test()
        {
            ... set things up ...
            thrown.expect(SomeException.class)
            callTheMethod();  / Preumably this throws SomeException
            ...
        }
    }
    
  3. # 3 楼答案

    一般来说,您的同事可能是对的,使用try-catch测试异常处理不如使用提供的ExpectedException实用程序。然而,我认为这条规则不适用于你的情况;捕捉异常以便验证其他事情是完全合理的。没有其他方法可以阻止异常传播,好吧

  4. # 4 楼答案

    对于特定于异常的断言AssertJ有一个很好的API:

    @Test
    public void testException() {
       assertThatThrownBy(() -> { throw new Exception("error!") })
         .isInstanceOf(Exception.class)
         .hasMessageContaining("error");
    }
    

    基本上,您可以在不中断测试执行的情况下“收集”异常