Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 测试引发异常的方法时验证行为_Java_Junit_Jmockit - Fatal编程技术网

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

Java 测试引发异常的方法时验证行为,java,junit,jmockit,Java,Junit,Jmockit,最近,在一次代码审查中,一位同事说“测试不应该有try-catch块”。他还向我指出了关于异常数据的信息,我能够用它重写一些对异常数据执行检查的测试 然而,我遇到了一种情况,我不确定我是否可以消除尝试捕捉。我正在为一个方法编写一个单元测试,该方法将抛出一个异常,,该异常将执行我需要使用JMockit验证的一些行为。假设测试中的代码包含如下内容 try { ...code... } catch (SomeException e) { statusMessage.send("Fail

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

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

try {
    ...code...
} catch (SomeException e) {
    statusMessage.send("Failure", <parameters with some data>);
    throw e;
}
试试看{
…代码。。。
}捕获(某些例外){
statusMessage.send(“失败”);
投掷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>);
    } }
}
@测试
公开无效测试(){
…把事情安排好。。。
试一试{
调用方法();
失败(“未引发异常”);
}捕获(例外e){
assertEquals(SomeException.class,例如getClass());
}
新验证(){{
statusMessage.send(“失败”);
} }
}
我找不到一个好办法来摆脱这种尝试性捕捞。就我个人而言,我不认为把它放在那里有什么问题,但如果我至少不设法摆脱它,我很可能会被我的同事吓到:):)

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

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

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

基于,我认为您可以执行以下操作:

class AjbUnitTest
{
    @Rule 
    public ExpectedException thrown = ExpectedException.none();

    @Test
    public void test()
    {
        ... set things up ...
        thrown.expect(SomeException.class)
        callTheMethod();  / Preumably this throws SomeException
        ...
    }
}

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

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

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

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

目前使用纯JUnit,如果要在抛出断言后验证某些内容,必须使用
try catch
。对于JUnit4.13(尚未发布),您可以使用

expectThrows(Exception.class, () -> callTheMethod());
new Verifications() { {
    statusMessage.send("Failure", <expected data>);
} }
expectThrows(Exception.class,()->callTheMethod());
新验证(){{
statusMessage.send(“失败”);
} }
作为替代方案,您可以使用

ignoreException(()->callTheMethod());
新验证(){{
statusMessage.send(“失败”);
} }

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

但是当
调用method()
抛出异常时,测试就结束了。如果该行后面有
验证
,则不会对其进行检查。我相信我已经测试过了,这就是我观察到的行为。哦,好的。如果你需要继续,那么你需要
try。。捕捉
。我认为这条规则是合理的,但如果有必要的话,可以打破规则。我认为这是一种情况。做一个笼统的声明说测试不应该有try-catch块是愚蠢的。相反,测试不应该捕获异常,除非该特定异常是测试的一部分。@gknicker您可以在前七个单词之后停止评论。可能是中间地带:而不是
assertEquals(..
您可以潜在地将
新验证
部分放入catch块,然后
抛出e
。不必亲自操心,因为您不仅对异常感兴趣,而且还对其间发生的事情感兴趣,这根本不是标准的“预期异常”测试。虽然您对
StatusMessage
的看法可能是正确的(我在实际代码中使用了模拟,但我只是想快速地将一个简化的示例组合在一起),这根本不能回答问题。@问题中提供的ajb代码被认为是问题的一部分。我认为它已经建立得很好了,所以如果你想说一些与提问者提出的问题无关的关于提问者代码的话,应该是一条注释,而不是单独的答案。太好了!这会很有用。不要想我们有可供生产使用的Fishbowl,因此我期待4.13的发布。如果没有Fishbowl,您可以简单地从Fishbowl复制
ignoreException
方法。
ignoreException(() -> callTheMethod());
new Verifications() { {
    statusMessage.send("Failure", <expected data>);
} }