Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

NPI – Spring Top – Temp – Non-Geo (Lightrun)

Get started with Spring 5 and Spring Boot 2, through the reference Learn Spring course:

>> LEARN SPRING
NPI – Lightrun – Spring (partner)

We rely on other people’s code in our own work. Every day. It might be the language you’re writing in, the framework you’re building on, or some esoteric piece of software that does one thing so well you never found the need to implement it yourself.

The problem is, of course, when things fall apart in production - debugging the implementation of a 3rd party library you have no intimate knowledge of is, to say the least, tricky. It’s difficult to understand what talks to what and, specifically, which part of the underlying library is at fault.

Lightrun is a new kind of debugger.

It's one geared specifically towards real-life production environments. Using Lightrun, you can drill down into running applications, including 3rd party dependencies, with real-time logs, snapshots, and metrics. No hotfixes, redeployments, or restarts required.

Learn more in this quick, 5-minute Lightrun tutorial:

>> The Essential List of Spring Boot Annotations and Their Use Cases

1. Introduction

ReflectionTestUtils is a part of the Spring Test Context framework. It's 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 learn how to use ReflectionTestUtils in unit testing by going through several examples.

2. Maven Dependencies

We'll start by adding the latest versions of all the necessary dependencies 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 and 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.

We'll start by creating it:

public class Employee {
    private Integer id;
    private String name;

    // standard getters/setters
}

Normally we can't access the private field id to assign a value for testing because there isn't a public setter method for it.

So we'll use the 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

Now let's imagine that we have a private method, employeeToString, in the 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 we 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);
    }
}

Now we can implement the HRService component as below:

@Component
public class HRService {

    public String getEmployeeStatus(Integer employeeId) {
        return "Inactive";
    }
}

Furthermore, we'll 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 the 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()));
}

We should note that this technique is a workaround for the fact that we're using field injection in our bean class. If we switched to constructor injection, then this approach wouldn't be necessary.

6. Conclusion

In this article, we demonstrated how to use ReflectionTestUtils in unit testing by going through several examples.

Code samples, as always, can be found over on Github.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> THE COURSE
Junit footer banner
Comments are closed on this article!