JUnit right way of test expected exceptions

后端 未结 4 1059
走了就别回头了
走了就别回头了 2020-12-15 20:37

Hello guys I was wondering if this way of testing my exception is ok, i have this exception i need to throw in the second test annotation, im receiving as result a red evil

相关标签:
4条回答
  • 2020-12-15 20:50

    You don't need to catch the Exception with try-catch

    @Test(expected = TramaConProtolocoloDesconocido.class)
    public void GTFRICreationTester_shouldFail()  {
    
        factory.createLocomotive(weirdProtocol, false, new Date());
    
    }
    

    If we suppose that factory.createLocomotive(weirdProtocol, false, new Date()) throws the exception when you apply a scenario that makes the exception thrown.

    void createLocomotive(param...) {
    
        //something...
    
        throw new TramaConProtolocoloDesconocido();
    }
    
    0 讨论(0)
  • 2020-12-15 20:56

    There is 3 most common ways to test expected exception:

    First one is the most common way, but you can test only the type of expected exception with it. This test will fail if ExceptionType won't be thrown:

    @Test(expected = ExceptionType.class)
    public void testSomething(){
        sut.doSomething();
    }
    

    Also you cannot specify the failure message using this approach

    The better option is to use ExpectedException JUnit @Rule. Here you can assert much more for expected exception

    @Rule
    public ExpectedException thrown = ExpectedException.none();
    
    @Test
    public void testSomething(){
        thrown.expect(ExceptionType.class);
        thrown.expectMessage("Error message");
        thrown.expectCause(is(new CauseOfExeption()));
        thrown.reportMissingExceptionWithMessage("Exception expected"); 
        //any other expectations
        sut.doSomething();
    }
    

    The third option will allow you to do the same as with using ExpectedException @Rule, but all the assertion should be written manually. However the advantage of this method is that you can use any custom assertion and any assertion library that you want:

    @Test
    public void testSomething(){
        try{
            sut.doSomething();
            fail("Expected exception");
        } catch(ExceptionType e) {
        //assert ExceptionType e
        } 
    }
    
    0 讨论(0)
  • 2020-12-15 21:06

    if your are using java 8, I would recommend to go for the AssertJ library

    public void GTFRICreationTester_shouldFail()  {
        assertThatExceptionOfType(EXCEPTION_CLASS).isThrownBy(() -> { factory.createLocomotive(weirdProtocol, false, new Date()) })
                                                   .withMessage("MESSAGE")
                                                   .withMessageContaining("MESSAGE_CONTAINING")
                                                   .withNoCause();         
    
        }
    

    with that solution you can at one verify exception type, with message etc.

    for more reading, take a look at: http://joel-costigliola.github.io/assertj/assertj-core-features-highlight.html#exception-assertion

    0 讨论(0)
  • 2020-12-15 21:09

    You can use ExpectedException which can provide you more precise information about the exception expected to be thrown with the ability to verify error message, as follows:

    import org.junit.Rule;
    import org.junit.Test;
    import org.junit.rules.ExpectedException;
    import org.junit.runner.RunWith;
    public class TestClass {
    
        @Rule
        public ExpectedException expectedException = ExpectedException.none();
    
    
        @Test
        public void GTFRICreationTester_shouldFail()  {
            expectedException.expect(TramaConProtolocoloDesconocido.class);
            factory.createLocomotive(weirdProtocol, false, new Date());
        }
    }
    

    To expolore more about it, you can refer to the blog written by me here - Expected Exception Rule and Mocking Static Methods – JUnit

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