In JUnit 5, the ParameterResolutionException occurs when JUnit fails to inject a dependency on a test method or constructor. JUnit 5 introduces the concept of dependency injection in test methods that allow services or mock objects to be injected directly into test classes. If the required settings do not exist, this can cause a ParameterResolutionException. In this article, we will explore how to resolve ParameterResolutionException in JUnit 5 using a hands-on example.
Prerequisites:
- Basic knowledge of Java and the JUnit framework.
- Maven for dependency management.
- JDK and IntelliJ IDEA installed in your system.
Parameter Resolution in JUnit 5
In JUnit 5, testing with dependency injection allows you to provide the necessary dependencies directly into test methods or constructors. This feature makes it easier to mock dependencies using tools like Mockito without having to write boilerplate code for setting up mocks. However, to fully utilize this feature and avoid common errors like the ParameterResolutionException, it is important to understand how JUnit 5 handles parameter resolution internally.
How Does It Work?
JUnit 5 introduces the Jupiter platform, which allows you to extend its functionality using extensions. One such extension is the Parameter Resolver, which handles the process of injecting dependencies into test methods. When a test method declares a parameter, JUnit attempts to find a registered ParameterResolver that can provide the required parameter.
The ParameterResolver does the following:
- It checks if it can resolve the specific parameter type for the given test method.
- If possible, it provides an instance of the required parameter during test execution.
If JUnit fails to find a suitable ParameterResolver for the parameter type, it throws a ParameterResolutionException. This often happens when using mock objects in JUnit tests without registering the required Mockito extension.
MockitoExtension in Focus
The MockitoExtension is a powerful JUnit 5 extension that:
- Automatically creates instances of fields annotated with
@Mock. - Injects these mock instances into fields or constructors annotated with
@InjectMocks. - Simplifies test setup, making test classes more readable and less cluttered with manual mock initialization.
Example of Using the MockitoExtension with JUnit 5:
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
@Mock
private UserRepository userRepository; // Creates a mock instance of UserRepository
@InjectMocks
private UserService userService; // Injects the mock into UserService
@Test
void testGetUserDetails() {
String userId = "user123";
when(userRepository.findUserById(userId)).thenReturn("John Doe");
String result = userService.getUserDetails(userId);
assertEquals("John Doe", result);
}
}
In the above example:
@ExtendWith(MockitoExtension.class) registers theMockitoExtension, enabling JUnit to recognize and inject mock objects.@Mocktells Mockito to create a mock instance ofUserRepository.@InjectMocksinstructs Mockito to inject theUserRepositorymock into theUserServiceinstance.
The MockitoExtension takes care of the parameter resolution process, ensuring that UserRepository is properly mocked and injected into UserService before the test method runs. This eliminates the need for manual setup and prevents ParameterResolutionException.
Implementation to Solve ParameterResolutionException in JUnit 5
Let's create a simple project demonstrating how to properly set up a test with dependency injection in JUnit 5.
Step 1: Create a Maven Project
Create a new Maven project in IntelliJ IDEA. Choose the following options:
- Name:
parameter-resolution-example - Build System: Maven
Click on the Create button.

Project Structure
Once project creation done, set the folder structure as shown in the below image:

Step 2: Add Dependencies in pom.xml
Open the pom.xml file and include the below JUnit 5 and Mockito dependencies in the project.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="https://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gfg</groupId>
<artifactId>parameter-resolution-example</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- JUnit 5 BOM for managed versions -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
<!-- Mockito for mocking -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.5.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.5.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
</plugin>
</plugins>
</build>
</project>
Step 3: Create the UserRepository Interface
package com.gfg;
public interface UserRepository {
String findUserById(String userId);
}
Step 4: Create the UserService Class
package com.example;
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public String getUserDetails(String userId) {
return userRepository.findUserById(userId);
}
}
Step 5: Main Class
package com.example;
public class Main {
public static void main(String[] args) {
UserRepository userRepository = new UserRepository() {
@Override
public String findUserById(String userId) {
if ("user123".equals(userId)) {
return "John Doe";
}
return "User Not Found";
}
};
UserService userService = new UserService(userRepository);
String userDetails = userService.getUserDetails("user123");
System.out.println("User Details: " + userDetails);
String nonExistentUserDetails = userService.getUserDetails("unknownUser");
System.out.println("User Details: " + nonExistentUserDetails);
}
}
Step 6: Write the Test Class
In this step, we will create a test class and will use the @ExtendWith annotation to enable dependency injection in JUnit 5.
UserServiceTest.java:
package com.example.service;
import com.gfg.UserRepository;
import com.gfg.UserService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;
@ExtendWith(MockitoExtension.class) // Enables parameter resolution for @Mock and @InjectMocks
public class UserServiceTest {
@Mock
private UserRepository userRepository; // Mocking UserRepository
@InjectMocks
private UserService userService; // Injecting the mock into UserService
@Test
public void testGetUserDetails() {
// Define behavior for the mock object
when(userRepository.findUserById("user123")).thenReturn("John Doe");
// Test the service method
String result = userService.getUserDetails("user123");
// Verify the result
assertEquals("John Doe", result);
verify(userRepository, times(1)).findUserById("user123");
}
}
Explanation:
- @ExtendWith(MockitoExtension.class) annotation enables the use of Mockito in JUnit 5, allowing for the parameter resolution of mocks.
- @Mock creates the mock instance of UserRepository.
- @InjectMocks injects the userRepository mock into userService.
- when(...).thenReturn(...) sets up mock behavior for findUserById method.
Step 7: Run the Application
Once the project is completed, we will run the application and it will display the below output:

Step 8: Running the Tests
We will now test the test suites using the following maven command:
mvn testOutput:
The expected output in the terminal will indicate that the tests passed:
