Java JUnit 测试——分析预期的异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4489801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:59:39  来源:igfitidea点击:

JUnit test — analysing expected Exceptions

javaexceptionjunit

提问by Farid

In JUnit, I'm currently using annotation to expect an exception in my tests.

在 JUnit 中,我目前正在使用注释来期待我的测试中出现异常。

Is there a way to analyse this exception? For example, I expect a CriticalServerException, but I also want to verify the content of the getMessagemethod.

有没有办法分析这个异常?例如,我期望 a CriticalServerException,但我也想验证getMessage方法的内容。

回答by Jigar Joshi

try{ 
    //your code expecting to throw an exception
    fail("Failed to assert :No exception thrown");
} catch(CriticalServerException ex){
    assertNotNull("Failed to assert", ex.getMessage()) 
    assertEquals("Failed to assert", "Expected Message", ex.getMessage());
}

回答by Ankit Bansal

I don't think there is a way of doing it using annotation. You may have to fall back to try-catch way where in the catch block you can verify the message

我认为没有办法使用注释来做到这一点。您可能不得不退回到 try-catch 方式,您可以在 catch 块中验证消息

回答by Brian

try
{
    // your code

    fail("Didn't throw expected exception");
}
catch(CriticalServerException e)
{
    assertEquals("Expected message", e.getMessage());
}

回答by Alex

try {
    // test code invacation
    fail("Exception not throw!!!");
} catch(CriticalServerException ex) {
    assertTrue("Invalid exception data", ex.toString().contains("error text"));
}

回答by Progman

I'm not sure if you should. Using a try-catch block to check the error message is so junit3ish. We have this cool feature now that you can write @Test(expected=CriticalServerException.class)and you want to go "back" and use try-catch again to fetch an exception you expect, just for checking the error message?

我不确定你是否应该这样做。使用 try-catch 块来检查错误消息是如此junit3ish。我们现在有这个很酷的功能,您可以编写@Test(expected=CriticalServerException.class)并且想要“返回”并再次使用 try-catch 来获取您期望的异常,只是为了检查错误消息?

IMO you should stay for the @Test(expected=CriticalServerException.class)annotation and ignore the error message. Checking the error message, which can be changed a lot as it is a more "human readable" string and not a technical value, can also be tricky. You are forcing the exception to have a specific error message, but you might not know who generated the exception and what error message he chose.

IMO 你应该留下@Test(expected=CriticalServerException.class)注释并忽略错误消息。检查错误消息也可能很棘手,因为它是一个更“人类可读”的字符串而不是技术值,因此可以对其进行大量更改。您正在强制异常具有特定的错误消息,但您可能不知道是谁生成了异常以及他选择了什么错误消息。

In general you want to test if the method throws the exception or not, and not what the actual error message looks like. If the error message is really so important you should maybe consider using a subclass of the exception it throws and check it in @Test(expected=...).

通常,您想测试该方法是否引发异常,而不是实际的错误消息是什么样的。如果错误消息真的很重要,您可能应该考虑使用它抛出的异常的子类并将其检入@Test(expected=...)

回答by u290629

Use MethodRuleas a common solution, if you have many test cases to test

如果您有许多测试用例要测试,请使用MethodRule作为通用解决方案

public class ExceptionRule implements MethodRule {
    @Override
    public Statement apply(final Statement base, final FrameworkMethod method, Object target) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                try {
                    base.evaluate();
                    Assert.fail();
                } catch (CriticalServerException e) {
                    //Analyze the exception here
                }
            }
        };    
    }
}

Then use the Rule to your test class:

然后将规则用于您的测试类:

@Rule public ExceptionRule rule = new ExceptionRule(); 

回答by Filippo Vitale

If you have JUnit 4.7or above try ExpectedException

如果您有JUnit 4.7或更高版本,请尝试ExpectedException

There is an example in this question, which is copied below:

这个问题中有一个例子,复制如下:

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

@Test
public void testRodneCisloRok(){
    exception.expect(IllegalArgumentException.class);
    exception.expectMessage("error1");
    new RodneCislo("891415",dopocitej("891415"));
}

回答by rwitzel

Use catch-exception:

使用捕获异常

catchException(obj).doSomethingCritical();
assertTrue(caughtException() instanceof CriticalServerException);
assertEquals("Expected Message", caughtException().getMessage());

回答by Marcin

Look at fluent-exception-rule, it "combines Junit ExpectedException rule and AssertJ's assertions convenience. "

看看fluent-exception-rule,它“结合了 Junit ExpectedException 规则和 AssertJ 的断言便利。”

import pl.wkr.fluentrule.api.FluentExpectedException;
...
@Rule
public FluentExpectedException thrown = FluentExpectedException.none();

@Test
public void testDoSomethingCritical() {
    thrown.expect(CriticalServerException.class).hasMessage("Expected Message").hasNoCause();
    obj.doSomethingCritical();
}

回答by Meet

If you want to compare message along with exception type then you can try below code snippet.

如果你想比较消息和异常类型,那么你可以尝试下面的代码片段。

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

    expectedException.expect(IllegalArgumentException.class);
    expectedException.expectMessage("Parameter is not valid"); //check string contains
    expectedException.expectMessage(CoreMatchers.equalTo("Parameter is not valid")); //check string equals

Note: This will work for junit 4.9 onward.

注意:这适用于 junit 4.9 以后。