简体   繁体   English

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

[英]Verifying behavior when testing a method that throws an exception

Recently, in a code review, a colleague said "Tests should not have try-catch blocks". 最近,在一次代码审查中,一位同事说“测试不应该有试试块”。 He also pointed me to information about ExpectedException , and I was able to use it to rewrite some of my tests that were performing checks on the exception data. 他还向我指出了有关ExpectedException信息,并且我能够使用它来重写我正在对异常数据执行检查的一些测试。

However, I'm encountering a situation where I'm not sure I can eliminate the try-catch. 但是,我遇到的情况是我不确定我是否可以消除try-catch。 I'm writing a unit test for a method that will throw an exception and that will perform some behavior that I need to verify using JMockit. 我正在为一个方法编写单元测试,该方法将抛出一个异常执行一些我需要使用JMockit验证的行为。 Suppose the code under test contains something like 假设测试中的代码包含类似的内容

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

The JUnit test currently looks like 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>);
    } }
}

I can't find a good way to get rid of the try-catch. 我找不到摆脱try-catch的好方法。 I don't see a problem with having it there, personally, but if I don't at least try to get rid of it I'm likely to catch heck from my colleague :) :) :) 我个人认为没有问题,但如果我不至少试图摆脱它,我很可能会赶上我的同事:) :) :)

The fail and assertEquals aren't necessary. failassertEquals不是必需的。 If there's a simple way to tell JUnit/JMockit to simply ignore any exception from callTheMethod() and continue, that would be fine--I can create another test to check the exception. 如果有一种简单的方法告诉JUnit / JMockit简单地忽略来自callTheMethod()任何异常并继续,那就没关系 - 我可以创建另一个测试来检查异常。

Is there some JUnit or JMockit feature that would let me accomplish what I'm trying to do? 是否有一些JUnit或JMockit功能可以让我完成我想要做的事情?

[Note: Edited to make it clear that the behavior I'm testing is a call on a mocked object, not a static method call. [注意:编辑清楚我正在测试的行为是对模拟对象的调用,而不是静态方法调用。 It really isn't relevant to the question.] 这与问题无关。]

Your colleague may be right in the general sense, using try-catch to test your exception handling is less desirable than using the provided ExpectedException utilities. 您的同事在一般意义上可能是正确的,使用try-catch测试您的异常处理比使用提供的ExpectedException实用程序更不可取。 However, I don't think that rule applies to your case; 但是,我不认为该规则适用于您的情况; catching the exception so you can verify other things is perfectly reasonable. 捕获异常,以便您可以验证其他事情是完全合理的。 There's no other way to stop an exception from from propagating, AFAIK. 没有其他方法可以阻止传播AFAIK的异常。

Currently with plain JUnit you have to use try-catch if you want to verify something after the assertion is thrown. 目前使用普通的JUnit,如果要在抛出断言后验证某些内容,则必须使用try-catch With JUnit 4.13 (not released yet) you can use 使用JUnit 4.13(尚未发布),您可以使用

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

As an alternative you can use the Fishbowl's ignoreException . 作为替代方案,您可以使用Fishbowl的ignoreException

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

Full disclosure: I'm the author of Fishbowl. 完全披露:我是Fishbowl的作者。

Based on the API , I'd say you could do something like: 根据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
        ...
    }
}

For exception specific assertions AssertJ has a good API: 对于异常特定的断言, AssertJ有一个很好的API:

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

Basically, you can "collect" the exception without disrupting the test execution. 基本上,您可以“收集”异常而不会中断测试执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM