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

发布于 2024-08-04 01:09:23 字数 204 浏览 2 评论 0原文

是否可以在单个 JUnit 单元测试中测试多个异常?我知道可以使用一个异常,例如

    @Test(expected=IllegalStateException.class)

现在,如果我想测试另一个异常(例如 NullPointerException),可以在同一个注释、不同的注释中完成,还是需要完全编写另一个单元测试?

Is it possible to test for multiple exceptions in a single JUnit unit test? 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

夏日浅笑〃 2024-08-11 01:09:23

您确实希望测试做一件事,并对其进行测试。如果您不确定将引发哪个异常,那么对我来说这听起来不是一个好的测试。

例如(在伪代码中),

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
}

所以如果您想测试您的方法是否抛出 2 个不同的异常(对于 2 组输入),那么您将需要 2 个测试。

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.

e.g. (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.

小兔几 2024-08-11 01:09:23

这对于注释来说是不可能的。

使用 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?");
    }
}

更多信息请参阅


如果您无法更新到 JUnit 4.7 ,您必须编写以下形式的裸单元测试

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

}

This is not possible with the annotation.

With JUnit 4.7 you can use the new ExpectedException rule

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

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

}

三生一梦 2024-08-11 01:09:23

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

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

Although this is not possible with JUnit 4, it is possible if you switch to TestNG, which allows you to write

@Test(expectedExceptions = {IllegalArgumentException.class, NullPointerException.class})
勿忘心安 2024-08-11 01:09:23

使用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);

}

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);

}
寂寞花火° 2024-08-11 01:09:23
@Test(expected=Exception.class)

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

@Test(expected=Exception.class)

This will throw all possible exceptions.

远山浅 2024-08-11 01:09:23

您希望“预期”如何发挥作用?一个方法只能抛出一个异常。

您必须为该方法可能失败的每种方式编写不同的单元测试。因此,如果该方法合法地抛出两个异常,那么您需要设置两个测试来强制该方法抛出每个异常。

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.

涙—继续流 2024-08-11 01:09:23

使测试尽可能简单和简短。 JUnit 测试的目的是仅测试一种简单的功能或一种单一的失败方式。

事实上,为了安全起见,您应该为每种可能的执行方式至少创建一个测试。

通常,这并不总是可能的,因为如果您有一个分析字符串的方法,那么可能的字符串组合有很多,您无法涵盖所有​​内容。

保持简短。

您可以轻松地为一种方法拥有 30-40 种测试方法...这真的很重要吗?

问候

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.

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?

Regards

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文