1. Overview

In this brief tutorial, we’ll explore the new @AutoClose JUnit 5 annotation, which helps us deal with classes that require a specific method call after test execution.

After that, we’ll learn how to use this extension to simplify our tests and remove boilerplate code from the @AfterAll block.

2. The @AutoClose Extension

In testing, there are scenarios where certain classes require specific actions to be performed after the test is completed. For example, this is often the case when we have test dependencies implementing the AutoCloseable interface. For demonstration purposes, let’s create our custom AutoCloseable class:

class DummyAutoCloseableResource implements AutoCloseable {
   
    // logger
   
    private boolean open = true;

    @Override
    public void close() {
        LOGGER.info("Closing Dummy Resource");
        open = false;
    }
}

When we finish running the tests, we close the resource using the @AfterAll block:

class AutoCloseableExtensionUnitTest {

    static DummyAutoCloseableResource resource = new DummyAutoCloseableResource();

    @AfterAll
    static void afterAll() {
        resource.close();
    }

    // tests
}

However, starting with JUnit5 version 5.11, we can use the @AutoClose extension to eliminate the boilerplate code. The extension is integrated into the JUnit5 framework, so we don’t need to add any special annotation at the class level. Instead, we can just annotate the field with @AutoClose:

class AutoCloseableExtensionUnitTest {

    @AutoClose
    DummyAutoCloseableResource resource = new DummyAutoCloseableResource();

    // tests
}

As we can see, this also removes the limitation of declaring the field static. Furthermore, the annotated field doesn’t necessarily have to implement the AutoCloseable interface. By default, the extension looks inside the annotated field and tries to find a method named “close“, but we can customize and point to a different function.

Let’s consider another use case, where we want to call the clear() method when we finished working with the resource:

class DummyClearableResource {
   
    // logger

    public void clear() {
        LOGGER.info("Clear Dummy Resource");
    }
}

In this case, we can use the annotation’s value to indicate which method needs to be called after all the tests:

class AutoCloseableExtensionUnitTest {

    @AutoClose
    DummyAutoCloseableResource resource = new DummyAutoCloseableResource();

    @AutoClose("clear")
    DummyClearableResource clearResource = new DummyClearableResource();

    // tests
}

3. Conclusion

In this short article, we discussed the new @AutoClose extension and used it for practical examples. We explored how it helps us keep tests concise and manage resources that need to be closed.

As usual, all code samples used in this article are available over on GitHub.