JUnit right way of test expected exceptions

杀马特。学长 韩版系。学妹 提交于 2019-11-29 03:31:35

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
    } 
}

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

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

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();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!