The TestInstancePreDestroyCallback defines the API for Extensions that wish to process test instances after they have been used but before they are destroyed. This is the last point in the lifecycle where an extension can interact with the specific test object.
Java source and doc
Definition of TestInstancePreDestroyCallbackVersion: 6.0.0 package org.junit.jupiter.api.extension;
@FunctionalInterface
@API(status = STABLE, since = "5.7")
public interface TestInstancePreDestroyCallback extends Extension {
void preDestroyTestInstance(ExtensionContext context) 1
throws Exception;
static void preDestroyTestInstances(ExtensionContext context, 2
Consumer<Object> callback);
}
Example
In this example, we implement a ResourceCleanupExtension that checks if the test instance implements AutoCloseable. If it does, the extension automatically invokes the close() method during the destruction phase.
package com.logicbig.example;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.TestInstancePreDestroyCallback;
public class ResourceCleanupExtension implements TestInstancePreDestroyCallback {
@Override
public void preDestroyTestInstance(ExtensionContext context) {
Object testInstance = context.getRequiredTestInstance();
System.out.println("Cleaning up resources for: " +
testInstance.getClass().getSimpleName());
if (testInstance instanceof AutoCloseable closeable) {
try {
closeable.close();
} catch (Exception e) {
System.err.println("Failed to close test instance: " + e.getMessage());
}
}
}
}
Test Class
package com.logicbig.example;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(ResourceCleanupExtension.class)
public class PreDestroyTest implements AutoCloseable {
@Test
void activeTest() {
System.out.println("Test is running...");
}
@Override
public void close() {
System.out.println("Resource closed via AutoCloseable");
}
}
Output$ mvn test -Dtest=PreDestroyTest [INFO] Scanning for projects... [INFO] [INFO] -------< com.logicbig.example:junit-5-test-instance-pre-destroy >------- [INFO] Building junit-5-test-instance-pre-destroy 1.0-SNAPSHOT [INFO] from pom.xml [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- resources:3.3.1:resources (default-resources) @ junit-5-test-instance-pre-destroy --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:\example-projects\junit-5\junit-5-extensions\junit-5-test-instance-pre-destroy\src\main\resources [INFO] [INFO] --- compiler:3.13.0:compile (default-compile) @ junit-5-test-instance-pre-destroy --- [INFO] No sources to compile [INFO] [INFO] --- resources:3.3.1:testResources (default-testResources) @ junit-5-test-instance-pre-destroy --- [WARNING] Using platform encoding (Cp1252 actually) to copy filtered resources, i.e. build is platform dependent! [INFO] skip non existing resourceDirectory D:\example-projects\junit-5\junit-5-extensions\junit-5-test-instance-pre-destroy\src\test\resources [INFO] [INFO] --- compiler:3.13.0:testCompile (default-testCompile) @ junit-5-test-instance-pre-destroy --- [INFO] Recompiling the module because of changed source code. [WARNING] File encoding has not been set, using platform encoding windows-1252, i.e. build is platform dependent! [INFO] Compiling 2 source files with javac [debug target 17] to target\test-classes [INFO] [INFO] --- surefire:3.5.0:test (default-test) @ junit-5-test-instance-pre-destroy --- [INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- Test is running... Cleaning up resources for: PreDestroyTest Resource closed via AutoCloseable [INFO] +--com.logicbig.example.PreDestroyTest - 0.110 ss [INFO] | '-- [OK] activeTest - 0.056 ss [INFO] [INFO] Results: [INFO] [INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 4.011 s [INFO] Finished at: 2025-12-31T14:56:46+08:00 [INFO] ------------------------------------------------------------------------
The execution log confirms that the 'close' method was called after the test method finished. This output proves that TestInstancePreDestroyCallback successfully intercepted the destruction phase, allowing for automated resource management. This pattern ensures that resources are always released, even if the developer forgets to add an explicit @AfterEach teardown method.
Example ProjectDependencies and Technologies Used: - junit-jupiter-engine 6.0.1 (Module "junit-jupiter-engine" of JUnit)
Version Compatibility: 5.6.0 - 6.0.1 Version compatibilities of junit-jupiter-engine with this example:
- 5.6.0
- 5.6.1
- 5.6.2
- 5.6.3
- 5.7.0
- 5.7.1
- 5.7.2
- 5.8.0
- 5.8.1
- 5.8.2
- 5.9.0
- 5.9.1
- 5.9.2
- 5.9.3
- 5.10.0
- 5.10.1
- 5.10.2
- 5.10.3
- 5.10.4
- 5.10.5
- 5.11.0
- 5.11.1
- 5.11.2
- 5.11.3
- 5.11.4
- 5.12.0
- 5.12.1
- 5.12.2
- 5.13.0
- 5.13.1
- 5.13.2
- 5.13.3
- 5.13.4
- 5.14.0
- 5.14.1
- 6.0.0
- 6.0.1
Versions in green have been tested.
- JDK 25
- Maven 3.9.11
|