What if your tests could get their setup data magically, without you writing the same code again and again?
Why ParameterResolver extension in JUnit? - Purpose & Use Cases
Imagine you have many test methods that need the same setup data or objects. You write code to create these objects inside each test method manually.
It feels like copying and pasting the same setup again and again.
This manual way is slow and boring. You might forget to update one test when the setup changes.
It also makes tests messy and hard to read because setup code mixes with test logic.
The ParameterResolver extension in JUnit helps by automatically providing the needed objects to your test methods.
You write the creation logic once, and JUnit injects the objects wherever needed.
This keeps tests clean, easy to maintain, and reduces mistakes.
@Test
void testA() {
User user = new User("Alice");
// test code
}
@Test
void testB() {
User user = new User("Alice");
// test code
}@ExtendWith(UserResolver.class) @Test void testA(User user) { // test code } @ExtendWith(UserResolver.class) @Test void testB(User user) { // test code }
You can write cleaner tests that automatically get the right data, making testing faster and less error-prone.
In a project, you need a database connection object in many tests. Using ParameterResolver, you create the connection once and inject it into all tests automatically.
Manual setup in each test is repetitive and error-prone.
ParameterResolver injects needed objects automatically into tests.
This leads to cleaner, easier-to-maintain test code.
Practice
ParameterResolver in JUnit 5?Solution
Step 1: Understand ParameterResolver role
A ParameterResolver is designed to supply values to parameters of test methods automatically, so tests don't need manual setup for those parameters.Step 2: Compare with other options
Options A, C, and D relate to other testing features but not to parameter injection.Final Answer:
To automatically provide values for test method parameters -> Option DQuick Check:
ParameterResolver = automatic parameter injection [OK]
- Confusing ParameterResolver with test ordering
- Thinking it creates mocks automatically
- Assuming it generates reports
ParameterResolver in JUnit 5?Solution
Step 1: Recall ParameterResolver interface methods
The ParameterResolver interface requires implementingsupportsParameterto check if a parameter is supported, andresolveParameterto provide the value.Step 2: Eliminate incorrect method pairs
Options A, B, and C list methods unrelated to ParameterResolver interface.Final Answer:
supportsParameter and resolveParameter -> Option AQuick Check:
ParameterResolver methods = supportsParameter + resolveParameter [OK]
- Confusing lifecycle methods with resolver methods
- Using incorrect method names
- Assuming initialization methods are required
class MyResolver implements ParameterResolver {
public boolean supportsParameter(ParameterContext pc, ExtensionContext ec) {
return pc.getParameter().getType() == String.class;
}
public Object resolveParameter(ParameterContext pc, ExtensionContext ec) {
return "InjectedValue";
}
}
@ExtendWith(MyResolver.class)
class TestClass {
@Test
void testMethod(String param) {
System.out.println(param);
}
}Solution
Step 1: Analyze supportsParameter method
It returns true only if the parameter type is String, so the test method's String param is supported.Step 2: Analyze resolveParameter method
It returns the string "InjectedValue", so this value will be injected into the test method parameter.Final Answer:
InjectedValue -> Option BQuick Check:
Parameter injection prints InjectedValue [OK]
- Assuming parameter is null if not supported
- Expecting compilation error due to interface methods
- Thinking test fails without explicit parameter value
class FaultyResolver implements ParameterResolver {
public boolean supportsParameter(ParameterContext pc, ExtensionContext ec) {
return pc.getParameter().getType() == Integer.class;
}
public Object resolveParameter(ParameterContext pc, ExtensionContext ec) {
return 42;
}
}
@ExtendWith(FaultyResolver.class)
class TestClass {
@Test
void testMethod(int param) {
System.out.println(param);
}
}Solution
Step 1: Check parameter type in supportsParameter
The test method parameter is primitiveint, but supportsParameter checks forInteger.class, which is the wrapper class. This causes supportsParameter to return false.Step 2: Understand consequence of mismatch
Because supportsParameter returns false, resolveParameter is never called, so the parameter is not injected, causing test failure or default value usage.Final Answer:
supportsParameter checks for Integer.class but parameter is primitive int -> Option CQuick Check:
Primitive vs wrapper mismatch breaks supportsParameter [OK]
- Ignoring difference between int and Integer
- Assuming @Override annotations are mandatory
- Thinking resolveParameter type must differ
String. Which implementation correctly achieves this and ensures a new UUID is generated for each test invocation?Solution
Step 1: Understand requirement for unique UUID per test
Each test invocation should get a new UUID string, so the UUID must be generated fresh every timeresolveParameteris called.Step 2: Evaluate options for UUID generation
InresolveParameter, returnUUID.randomUUID().toString()without caching generates a new UUID string on each call, fulfilling the requirement. Options B, C, and D cache or fix the UUID, so they do not produce unique values per test.Final Answer:
In resolveParameter, return UUID.randomUUID().toString() without caching -> Option AQuick Check:
Generate UUID fresh in resolveParameter for uniqueness [OK]
- Caching UUID and returning same value every time
- Generating UUID once in constructor
- Returning fixed string instead of UUID
Ready to prove it?
Pass the test and this pattern moves unknown
