Testing for multiple exceptions with JUnit 4 annotations

后端 未结 7 2253
-上瘾入骨i
-上瘾入骨i 2020-12-30 22:06

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=Illega         


        
相关标签:
7条回答
  • 2020-12-30 22:19
    @Test(expected=Exception.class)
    

    This will throw all possible exceptions.

    0 讨论(0)
  • 2020-12-30 22:23

    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

    • JUnit 4.7: Interceptors: expected exceptions
    • Rules in JUnit 4.7

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

    }

    0 讨论(0)
  • 2020-12-30 22:25

    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.

    0 讨论(0)
  • 2020-12-30 22:32

    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.

    0 讨论(0)
  • 2020-12-30 22:38

    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})
    
    0 讨论(0)
  • 2020-12-30 22:41

    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

    0 讨论(0)
提交回复
热议问题