The extension model in JUnit helps you add extra features to your tests easily. It lets you run code before or after tests, change how tests behave, and share setup steps.
Extension model overview in JUnit
@ExtendWith(YourExtension.class) public class YourTestClass { // test methods }
Use @ExtendWith annotation to register an extension on a test class or method.
Extensions implement interfaces like BeforeEachCallback, AfterEachCallback, etc.
@ExtendWith(TimingExtension.class) public class MyTests { @Test void testExample() { // test code } }
public class RetryExtension implements TestExecutionExceptionHandler { @Override public void handleTestExecutionException(ExtensionContext context, Throwable throwable) throws Throwable { // retry logic here } } @ExtendWith(RetryExtension.class) public class RetryTests { @Test void flakyTest() { // test that might fail sometimes } }
This test class uses a simple extension that prints messages before and after each test runs.
import org.junit.jupiter.api.extension.*; import org.junit.jupiter.api.*; class SimpleExtension implements BeforeEachCallback, AfterEachCallback { @Override public void beforeEach(ExtensionContext context) { System.out.println("Starting test: " + context.getDisplayName()); } @Override public void afterEach(ExtensionContext context) { System.out.println("Finished test: " + context.getDisplayName()); } } @ExtendWith(SimpleExtension.class) public class ExtensionModelTest { @Test void testOne() { Assertions.assertTrue(true); } @Test void testTwo() { Assertions.assertEquals(2, 1 + 1); } }
Extensions can be reused across many test classes to keep code clean.
JUnit provides many built-in extension points like lifecycle callbacks and parameter resolvers.
Custom extensions must implement specific interfaces depending on what they do.
The extension model lets you add extra behavior to tests without changing test code.
Use @ExtendWith to apply extensions to tests.
Extensions can run code before/after tests, handle exceptions, or change test execution.
Practice
Solution
Step 1: Understand the extension model concept
The extension model allows adding extra behavior to tests without modifying the original test code.Step 2: Compare options with the concept
Only To add extra behavior to tests without changing the test code correctly describes this purpose. Other options describe unrelated features.Final Answer:
To add extra behavior to tests without changing the test code -> Option AQuick Check:
Extension model purpose = add behavior without code change [OK]
- Confusing extension model with test data generation
- Thinking it replaces assertions
- Assuming it speeds up test writing
Solution
Step 1: Recall the correct annotation for extensions
JUnit uses@ExtendWithto apply extensions to test classes or methods.Step 2: Verify other options
Options B, C, and D are not valid JUnit annotations for extensions.Final Answer:
@ExtendWith -> Option AQuick Check:
Extension annotation = @ExtendWith [OK]
- Using @TestExtension which does not exist
- Confusing with @UseExtension or @EnableExtension
- Forgetting the '@' symbol
@ExtendWith(MyExtension.class)
class MyTest {
@Test
void testMethod() {
System.out.println("Test running");
}
}
class MyExtension implements BeforeTestExecutionCallback {
public void beforeTestExecution(ExtensionContext context) {
System.out.println("Before test");
}
}Solution
Step 1: Understand the extension callback
TheBeforeTestExecutionCallbackruns its method before the test method executes, printing "Before test" first.Step 2: Order of print statements
First "Before test" prints, then the test method prints "Test running".Final Answer:
Before test\nTest running -> Option BQuick Check:
BeforeTestExecutionCallback runs before test method [OK]
- Assuming test method prints first
- Confusing callback timing
- Ignoring extension execution order
public class MyExtension implements BeforeTestExecutionCallback {
public void beforeTestExecution() {
System.out.println("Before test");
}
}Solution
Step 1: Check method signature for interface implementation
The interfaceBeforeTestExecutionCallbackrequiresbeforeTestExecution(ExtensionContext context)method with one parameter.Step 2: Identify missing parameter
The method in the code has no parameters, so it does not correctly implement the interface.Final Answer:
Missing parameter ExtensionContext in beforeTestExecution method -> Option DQuick Check:
Interface method requires ExtensionContext parameter [OK]
- Omitting required method parameters
- Changing method return type incorrectly
- Using wrong method names
Solution
Step 1: Understand callback interfaces for test methods
BeforeEachCallbackruns before each test method, andAfterEachCallbackruns after each test method.Step 2: Match requirement to interfaces
To log before and after each test method, implement bothBeforeEachCallbackandAfterEachCallback.Final Answer:
BeforeEachCallback and AfterEachCallback -> Option CQuick Check:
Before/After each test = BeforeEachCallback + AfterEachCallback [OK]
- Using BeforeAllCallback which runs once per class
- Confusing AfterTestExecutionCallback with AfterEachCallback
- Choosing exception handler interfaces incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
