SpringBoot : How ReflectionTestUtils.setFields work?

Issue

Consider the below code:

Service

class MyService{

  @Autowired
  private ModelMapper modelMapper;


  void validate(){

       ResponseObject obj = modelMapper.map( REQUEST, ResponseObject.class);
 
       // In testing, if I am not mocking this Model Mapper, an exception will be thrown.

  }

}

Testing

Here in JUnit test cases, instead of mocking, I am making use of ReflectionTestUtils.setField("", "", "") and the mapping takes place as expected. But I am not aware of what’s happening and how it’s working. I referred to many sources, but I couldn’t find any reliable resource regarding this. Can someone tell me whats ReflectionTestUtils, how its works, and when to use it?

@InjectMocks
MyService service;

private ModelMapper modelMapper;

@BeforeEach
void setup() {
    modelMapper = new ModelMapper();
    ReflectionTestUtils.setField( service, "modelMapper", modelMapper);

}

Solution

It uses reflection API under the cover to set the value for an object ‘s field.

About when to use it , the documentation already provides some info :

You can use these methods in testing scenarios where you need to
change the value of a constant, set a non-public field, invoke a
non-public setter method, or invoke a non-public configuration or
lifecycle callback method when testing application code for use cases
such as the following:

  • ORM frameworks (such as JPA and Hibernate) that condone private or
    protected field access as opposed to public setter methods for
    properties in a domain entity.

  • Spring’s support for annotations (such as @Autowired, @Inject, and
    @Resource), that provide dependency injection for private or protected
    fields, setter methods, and configuration methods.

  • Use of annotations such as @PostConstruct and @PreDestroy for
    lifecycle callback methods.

I normally use it for setting up some dummy domain objects which are JPA entities for testing. Since their ID are managed by Hibernate and to have a good encapsulation , they do not have any setter or constructor to configure their ID value , and hence need to use it to setup some dummy values for their ID.

Answered By – Ken Chan

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published