简体   繁体   English

使用 JUnit 4 注释测试多个异常

[英]Testing for multiple exceptions with JUnit 4 annotations

Is it possible to test for multiple exceptions in a single JUnit unit test?是否可以在单个 JUnit 单元测试中测试多个异常? I know for a single exception one can use, for example我知道一个可以使用的异常,例如

    @Test(expected=IllegalStateException.class)

Now, if I want to test for another exception (say, NullPointerException), can this be done in the same annotation, a different annotation or do I need to write another unit test completely?现在,如果我想测试另一个异常(比如 NullPointerException),是否可以在同一个注释、不同的注释中完成,或者我是否需要完全编写另一个单元测试?

You really want the test to do one thing, and to test for that.你真的希望测试做件事,并为此进行测试。 If you're not sure as to which exception is going to be thrown, that doesn't sound like a good test to me.如果您不确定要抛出哪个异常,那对我来说听起来不是一个好的测试。

eg (in pseudo-code)例如(在伪代码中)

try {
   badOperation();
   /// looks like we succeeded. Not good! Fail the test
   fail();
}
catch (ExpectedException e) {
   // that's fine
}
catch (UnexpectedException e) {
   // that's NOT fine. Fail the test
}

so if you want to test that your method throws 2 different exceptions (for 2 sets of inputs), then you'll need 2 tests.因此,如果您想测试您的方法是否引发了 2 个不同的异常(对于 2 组输入),那么您将需要 2 个测试。

This is not possible with the annotation.这对于注释是不可能的。

With JUnit 4.7 you can use the new ExpectedException rule使用 JUnit 4.7,您可以使用新的ExpectedException规则

public static class HasExpectedException {
    @Interceptor
    public ExpectedException thrown= new ExpectedException();

    @Test
    public void throwsNothing() {
    }

    @Test
    public void throwsNullPointerException() {
         thrown.expect(NullPointerException.class);
         throw new NullPointerException();
    }

    @Test
    public void throwsNullPointerExceptionWithMessage() {
        thrown.expect(NullPointerException.class);
        thrown.expectMessage("happened?");
        throw new NullPointerException("What happened?");
    }
}

More see更多见


If updating to JUnit 4.7 is not possible for you, you have to write a bare unit test of the form如果您无法更新到 JUnit 4.7,则必须编写表单的裸单元测试

public test() {
    try {
        methodCall(); // should throw Exception
        fail();
    }
    catch (Exception ex) {
        assert((ex instanceof A) || (ex instanceof B) || ...etc...);
        ...
    }

} }

虽然这在 JUnit 4 中不可能的,但是如果您切换到 TestNG,它允许您编写

@Test(expectedExceptions = {IllegalArgumentException.class, NullPointerException.class})

Use catch-exception :使用捕获异常

// test 
public void testDo() {

   // obj.do(1) must throw either A or B
   catchException(obj).do(1);
   assert caughtException() instanceof A
       || caughtException() instanceof B;

   // obj.do(2) must throw A but not SubclassOfA
   catchException(obj).do(2);
   assert caughtException() instanceof A
       && !(caughtException() instanceof SubclassOfA);

}
@Test(expected=Exception.class)

这将抛出所有可能的异常。

How would you expect to "expected"s to work?您如何期望“预期”工作? A method can only throw one exception.一个方法只能抛出一个异常。

You would have to write a different unit test for each way the method can fail.您必须为方法可能失败的每种方式编写不同的单元测试。 So if the method legitimately throw two exceptions then you need two tests set up to force the method of throwing each exception.因此,如果该方法合法地抛出两个异常,那么您需要设置两个测试来强制抛出每个异常的方法。

Keep the tests as simple and short as possible.使测试尽可能简单和简短。 The intention of a JUnit-Test is to test only one simple functionality or one single way of failure. JUnit-Test 的目的是只测试一种简单的功能或一种单一的失败方式。

Indeed, to be safe, you should create at least one test for every possible execution way.实际上,为了安全起见,您应该为每种可能的执行方式至少创建一个测试。

Normally, this is not always possible because if you have a method that analyses a string, there are so many possible string combinations that you cannot cover everything.通常,这并不总是可行的,因为如果您有一种分析字符串的方法,那么可能的字符串组合太多,您无法涵盖所有​​内容。

Keep it short and simple.保持简短。

You can have 30-40 testing methods for one single method easily... does it really matter?对于一种方法,您可以轻松拥有 30-40 种测试方法……这真的很重要吗?

Regards问候

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

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