Tuesday, June 6, 2017

Testing exceptions with JUnit 5

JUnit 5 brought pretty awesome improvements and it differs a lot from its predecessor. JUnit 5 requires Java 8 at runtime hence Lambda expressions can be used in tests, especially in assertions. One of those assertions is perfectly suited for testing exceptions.

Setup the project

To demonstrate JUnit 5 usage I used my long-lived unit-testing-demo Github project as it already contains many unit testing samples: https://github.com/kolorobot/unit-testing-demo. Adding JUnit 5 support to an existing project is straightforward: apart from all standard JUnit 5 dependencies a junit-vintage-engine must exist in test runtime path:

    // JUnit 5 Jupiter API and TestEngine implementation
    testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0-M4")
    testRuntime("org.junit.jupiter:junit-jupiter-engine:5.0.0-M4")

    // Support JUnit 4 tests
    testCompile("junit:junit:4.12")
    testRuntime("org.junit.vintage:junit-vintage-engine:4.12.0-M4")

JUnit 5 assertThrows

JUnit 5 built-in org.junit.jupiter.api.Assertions#assertThrows gets expected exception class as first parameter and the executable (functional interface) potentially throwing an exception as the second. The method will fail if no exception or exception of different type is thrown. The method returns the exception itself that can be used for further assertions:

import org.junit.jupiter.api.*;

import static org.junit.jupiter.api.Assertions.*;

class Junit5ExceptionTestingTest { // non public, new to JUnit5

    @Test
    @DisplayName("Junit5 built-in Assertions.assertThrows and Assertions.assertAll")
    @Tag("exception-testing")
    void verifiesTypeAndMessage() {
        Throwable throwable = assertThrows(MyRuntimeException.class, new Thrower()::throwsRuntime);

        assertAll(
            () -> assertEquals("My custom runtime exception", throwable.getMessage()),
            () -> assertNull(throwable.getCause())
        );
    }
}

Summary

In JUnit 4 there are many ways of testing exceptions in test code, including try-catch idiom, JUnit @Rule or AssertJ (3+). As of JUnit 5 a built-in assertion can be used.

References

0 komentarze:

Post a Comment