在测试抛出异常的方法时验证行为

时间:2015-11-18 04:17:19

标签: java junit jmockit

最近,在一次代码审查中,一位同事说“测试不应该有试试块”。他还向我指出了有关ExpectedException的信息,并且我能够使用它来重写我正在对异常数据执行检查的一些测试。

然而,我遇到的情况是我不确定我是否可以消除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>);
    } }
}

我找不到摆脱try-catch的好方法。我个人认为没有问题,但如果我至少尝试摆脱它,我很可能抓住来自我的同事:) :) :)

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

是否有一些JUnit或JMockit功能可以让我完成我想要做的事情?

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

4 个答案:

答案 0 :(得分:2)

您的同事在一般意义上可能是正确的,使用try-catch来测试您的异常处理比使用提供的ExpectedException实用程序更不可取。但是,我并不认为该规则适用于您的案件;捕获异常,以便您可以验证其他事情是完全合理的。没有其他方法可以阻止传播AFAIK的异常。

答案 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>);
} }

完全披露:我是Fishbowl的作者。

答案 2 :(得分:-1)

根据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 :(得分:-2)

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

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

基本上,你可以&#34;收集&#34;例外,不会中断测试执行。