1. Introduction
ReflectionTestUtils is a part of Spring Test Context framework. It is a collection for reflection-based utility methods used in a unit, and integration testing scenarios to set the non-public fields, invoke non-public methods, and inject dependencies.
In this tutorial, we’ll take a look at how we can use the ReflectionTestUtils in unit testing by going through several examples.
2. Maven Dependencies
Let’s start by adding the latest versions of all necessary dependencies needed for our examples to our pom.xml:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.1.2.RELEASE</version> <scope>test</scope> </dependency>
The latest spring-context, spring-test dependencies can be downloaded from the Maven Central repository.
3. Using ReflectionTestUtils to Set a Value of a Non-Public Field
Suppose we need to use an instance of a class having a private field without a public setter method in our unit test.
Let’s start by creating it:
public class Employee { private Integer id; private String name; // standard getters/setters }
Normally we cannot access the private field id to assign a value for testing, because there isn’t a public setter method for it.
We can then use ReflectionTestUtils.setField method to assign a value to the private member id:
@Test public void whenNonPublicField_thenReflectionTestUtilsSetField() { Employee employee = new Employee(); ReflectionTestUtils.setField(employee, "id", 1); assertTrue(employee.getId().equals(1)); }
4. Using ReflectionTestUtils to Invoke a Non-Public Method
Let’s now imagine that we have a private method employeeToString in Employee class:
private String employeeToString(){ return "id: " + getId() + "; name: " + getName(); }
We can write a unit test for the employeeToString method as below, even though it doesn’t have any access from outside of an Employee class:
@Test public void whenNonPublicMethod_thenReflectionTestUtilsInvokeMethod() { Employee employee = new Employee(); ReflectionTestUtils.setField(employee, "id", 1); employee.setName("Smith, John"); assertTrue(ReflectionTestUtils.invokeMethod(employee, "employeeToString") .equals("id: 1; name: Smith, John")); }
5. Using ReflectionTestUtils to Inject Dependencies
Let’s say that want to write a unit test for the following Spring component having a private field with the @Autowired annotation:
@Component public class EmployeeService { @Autowired private HRService hrService; public String findEmployeeStatus(Integer employeeId) { return "Employee " + employeeId + " status: " + hrService.getEmployeeStatus(employeeId); } }
We can now implement the HRService component as below:
@Component public class HRService { public String getEmployeeStatus(Integer employeeId) { return "Inactive"; } }
Furthermore, let’s create a mock implementation for the HRService class by using Mockito. We’ll inject this mock into the EmployeeService instance, and we’ll use it in our unit test:
HRService hrService = mock(HRService.class); when(hrService.getEmployeeStatus(employee.getId())).thenReturn("Active");
Because hrService is a private field without a public setter, we’ll use ReflectionTestUtils.setField method to inject the mock we created above into this private field.
EmployeeService employeeService = new EmployeeService(); ReflectionTestUtils.setField(employeeService, "hrService", hrService);
Finally, our unit test will look similar to this:
@Test public void whenInjectingMockOfDependency_thenReflectionTestUtilsSetField() { Employee employee = new Employee(); ReflectionTestUtils.setField(employee, "id", 1); employee.setName("Smith, John"); HRService hrService = mock(HRService.class); when(hrService.getEmployeeStatus(employee.getId())).thenReturn("Active"); EmployeeService employeeService = new EmployeeService(); // Inject mock into the private field ReflectionTestUtils.setField(employeeService, "hrService", hrService); assertEquals( "Employee " + employee.getId() + " status: Active", employeeService.findEmployeeStatus(employee.getId())); }
6. Conclusion
In this tutorial, we showed how to use ReflectionTestUtils in unit testing by going through several examples.
Code samples, as always, can be found over on Github.