sebastiandaschner blog

First look at JUnit 5

thursday, july 14, 2016

In July the first milestone of JUnit 5 was released. This new version will make use of Java 8 lambdas and will redesign some JUnit core features.

What’s new

Some of the main changes in the way how we’ll write JUnit tests are:

  • New package org.junit.jupiter.api — instead of good old org.junit

  • @BeforeEach, @BeforeAll, @AfterEach, @AfterAll — instead of the ones known now

  • @Disabled to disable tests — instead of @Ignored

  • @ExtendedWith supersedes @RunWith and @Rule

  • DynamicTests supersede Parameterized tests

  • Assertions#expectThrows for expected exceptions

The 5.0.0-M1 version can be used from Maven central:




How to use

Following example of a functionality and its test:

public class FunWithStrings {

    public String getStringLength(final String string) {
        return string + ':' + string.length();

public class FunWithStringsTest {

    private FunWithStrings cut = new FunWithStrings();

    // first, simple test
    public void testGetStringLengthSimpleTest() {
        assertEquals("hello:5", cut.getStringLength("hello"), () -> "'hello' (length: 5) wasn't calculated properly");

    public Stream<DynamicTest> createGetStringLengthTests() {
        final String[][] data = {
                // input, expected
                {"hello", "hello:5"},
                {"hel", "hel:3"},
                {"h", "h:1"},
                {"", ":0"},
                {" ", " :1"}

        return Stream.of(data).map(o -> dynamicTest("test: " + o[0], () -> assertEquals(o[1], cut.getStringLength(o[0]))));

    public void testNull() {
        expectThrows(NullPointerException.class, () -> cut.getStringLength(null));


The method annotated with @TestFactory is not a test itself but creates a stream of dynamic tests — in this usage similar to the idea of Parameterized tests of JUnit 4.

The following example shows how more sophisticated test scenarios could be realized. Imagine a system test scenario testing a resource which is available only after some startup time. The test should wait within a timeout for the resource being available.

Prior to JUnit 5 this could be realized with an @Rule.

public class SystemTest {

    public void test(final MockedSystem mockedSystem) {
        final Response response =;

        assertEquals(response.getStatusInfo().getFamily(), Response.Status.Family.SUCCESSFUL, () -> "status code is not 2xx");
        assertEquals(response.getHeaderString("X-Hello"), "World", () -> "header 'X-Hello' not correct");


The MockedSystem can be injected in the test method due to the registered extension:

public class MockedSystemExtension implements ParameterResolver {

    public boolean supports(final ParameterContext parameterContext, final ExtensionContext extensionContext) throws ParameterResolutionException {
        return parameterContext.getParameter().getType().isAssignableFrom(MockedSystem.class);

    public Object resolve(final ParameterContext parameterContext, final ExtensionContext extensionContext) throws ParameterResolutionException {
        final MockedSystem mockedSystem = new MockedSystem();


        return mockedSystem;

    private void waitForStartUp(MockedSystem mockedSystem) {
        // ...


The system simulates a WebTarget which normally would be used to access an API.

Here I use Mockito to simulate a system which takes 10 seconds to start up.

public class MockedSystem {

    private static final int STARTUP_TIME = 10;

    private final WebTarget target;

    MockedSystem() {
        final WebTarget tut = mock(WebTarget.class);
        final Invocation.Builder builder = mock(Invocation.Builder.class);
        final Response notFoundResponse = mock(Response.class);
        final Response okResponse = mock(Response.class);
        final long start = System.currentTimeMillis();

        when(builder.get()).then(a -> {
            if (System.currentTimeMillis() - start < STARTUP_TIME * 1000)
                return notFoundResponse;
            return okResponse;


        when(okResponse.getHeaders()).thenReturn(new MultivaluedHashMap<>(Collections.singletonMap("X-Hello", "World")));
        when(okResponse.getHeaderString(anyString())).then(a -> ((Response) a.getMock()).getHeaders().getFirst(a.getArgument(0))); = tut;

    public WebTarget target() {
        return target;


Therefore the SystemTest can rely that the injected MockedSystem was probed to be available before — transparent to the test class itself.

Further reading

These snippets are taken from my JUnit 5 Playground GitHub project.

Also see the JUnit 5 User Guide.

Happy testing!


Found the post useful? Subscribe to my newsletter for more free content, tips and tricks on IT & Java: