BeforeEachCallback and AfterEachCallback in JUnit - Build an Automation Script
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.AfterEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ExtendWith; import static org.junit.jupiter.api.Assertions.assertTrue; class SetupCleanupExtension implements BeforeEachCallback, AfterEachCallback { @Override public void beforeEach(ExtensionContext context) { System.out.println("Setup before each test"); } @Override public void afterEach(ExtensionContext context) { System.out.println("Cleanup after each test"); } } @ExtendWith(SetupCleanupExtension.class) public class SampleTest { @Test void testOne() { assertTrue(1 + 1 == 2); } @Test void testTwo() { assertTrue("hello".startsWith("h")); } }
This code defines a class SetupCleanupExtension that implements BeforeEachCallback and AfterEachCallback. The beforeEach method prints a setup message before each test, and the afterEach method prints a cleanup message after each test.
The test class SampleTest uses @ExtendWith to register this extension. It contains two simple test methods with assertions that always pass.
When running the tests, the console will show the setup message before each test and the cleanup message after each test, demonstrating the callbacks work as expected.
Now add a data-driven test that runs the same test logic with three different input values using @ParameterizedTest
Practice
BeforeEachCallback and AfterEachCallback in JUnit 5?Solution
Step 1: Understand the role of BeforeEachCallback and AfterEachCallback
These interfaces allow running code before and after each test method, typically for setup and cleanup.Step 2: Compare with other lifecycle callbacks
Unlike @BeforeAll or @AfterAll, these run before and after every test, not once per class.Final Answer:
To run code before and after each test method for setup and cleanup -> Option BQuick Check:
BeforeEachCallback and AfterEachCallback = setup and cleanup per test [OK]
- Confusing with @BeforeAll/@AfterAll which run once per class
- Thinking they replace test methods
- Assuming they skip tests
BeforeEachCallback interface in JUnit 5?Solution
Step 1: Recall the method signature for BeforeEachCallback
The interface requires implementingbeforeEach(ExtensionContext context)to run code before each test.Step 2: Differentiate from other lifecycle methods
Methods like beforeAll or afterAll belong to other interfaces or annotations, not BeforeEachCallback.Final Answer:
void beforeEach(ExtensionContext context) -> Option AQuick Check:
BeforeEachCallback method = beforeEach() [OK]
- Using beforeAll or afterAll methods incorrectly
- Confusing AfterEachCallback method with BeforeEachCallback
- Missing the ExtensionContext parameter
public class MyExtension implements BeforeEachCallback, AfterEachCallback {
@Override
public void beforeEach(ExtensionContext context) {
System.out.println("Start " + context.getDisplayName());
}
@Override
public void afterEach(ExtensionContext context) {
System.out.println("End " + context.getDisplayName());
}
}Assuming the test method is named
testExample() in class ExampleTest.Solution
Step 1: Understand what context.getDisplayName() returns
It returns the display name of the current test, typically in the format "methodName(className)".Step 2: Analyze the print statements in beforeEach and afterEach
Before the test, it prints "Start " plus the display name; after the test, it prints "End " plus the same display name.Final Answer:
Start testExample(ExampleTest) End testExample(ExampleTest) -> Option DQuick Check:
beforeEach prints Start + displayName, afterEach prints End + displayName [OK]
- Assuming displayName returns only class or method name
- Thinking only one print runs
- Mixing order of prints
AfterEachCallback:public class CleanupExtension implements AfterEachCallback {
public void afterEach() {
System.out.println("Cleaning up after test");
}
}Solution
Step 1: Check method signature for AfterEachCallback
The interface requires implementingafterEach(ExtensionContext context)with the ExtensionContext parameter.Step 2: Identify the missing parameter error
The code's afterEach method has no parameters, so it does not correctly override the interface method.Final Answer:
Missing ExtensionContext parameter in afterEach method -> Option CQuick Check:
AfterEachCallback.afterEach() requires ExtensionContext parameter [OK]
- Omitting ExtensionContext parameter
- Making method static incorrectly
- Thinking BeforeEachCallback is mandatory
- Believing print statements are disallowed
BeforeEachCallback and AfterEachCallback to achieve this?Solution
Step 1: Understand lifecycle of BeforeEachCallback and AfterEachCallback
They run before and after each test method, so storing start time in a field allows sharing data between these callbacks for the same test.Step 2: Evaluate options for storing start time
Local variables in beforeEach cannot be accessed in afterEach; static variables cause data sharing issues across tests; logging elapsed time in test method breaks separation of concerns.Final Answer:
Store start time in a field in beforeEach, then calculate elapsed time in afterEach using the same field -> Option AQuick Check:
Use instance field to share data between beforeEach and afterEach [OK]
- Trying to share data via local variables
- Using static fields causing test interference
- Logging elapsed time inside test methods
Ready to prove it?
Pass the test and this pattern moves unknown
