I want to mock a RestTemplate
in Spring Boot, where I'm making a REST call within a method. To test the controller of the microservice I'm creating,
I want to test methods inside the controller of my micro service.
For example:
@GetMapping(value = "/getMasterDataView", produces = { MediaType.APPLICATION_JSON_VALUE })
@CrossOrigin(origins = { "http://192.1**********" }, maxAge = 3000)
public ResponseEntity<MasterDataViewDTO> getMasterDataView() throws IOException {
final String uri = "http://localhost:8089/*********";
RestTemplate restTemplate = new RestTemplate();
MasterDataViewDTO masterDataViewDTO = restTemplate.getForObject(uri, MasterDataViewDTO.class);
return new ResponseEntity<>(masterDataViewDTO, HttpStatus.OK);
}
how to I test this using mocking?
This is what I have so far:
@Test
public void testgetMasterDataView() throws IOException {
MasterDataViewDTO masterDataViewDTO= mock(MasterDataViewDTO.class);
//String uri = "http://localhost:8089/*********";
Mockito.when(restTemplate.getForObject(Mockito.anyString(),ArgumentMatchers.any(Class.class))).thenReturn(masterDataViewDTO);
assertEquals("OK",inquiryController.getMasterDataView().getStatusCode());
}
I am getting an error when I'm running the mock, the method getMasterDataView()
is getting called and the REST call within it is also getting called and is throwing an error. How can I write my test so that the REST endpoint is not called? If it's possible, I'd like to do this with Mockito.
Before you start writing a test, you should change your code a bit. First of all, it would be a lot easier if you extracted that
RestTemplate
, and created a separate bean for it which you would inject within your controller.To do that, add something like this within a
@Configuration
class or within your main class:Additionally, you have to remove the
new RestTemplate()
from your controller, and autowire it in stead, for example:Now that you've done that, it's going to be a lot easier to inject a mock
RestTemplate
within your tests.For your testing, you have two options:
RestTemplate
and all the methods you are trying to access, using a mocking framework (eg. Mockito)MockRestServiceServer
, which allows you to write tests that verify if the URLs are properly called, the request matches, and so on.Testing with Mockito
To mock your
RestTemplate
with Mockito, you have to make sure that you add the following annotation to your tests:After that, you can do this:
And now you can adjust your tests like this:
You could mock the DTO as you did within your test, but you don't have to, and I don't think there's any benefit from doing so. What you do have to mock is the
restTemplate.getForObject(..)
call.Testing with
MockRestServiceServer
Another approach is to use
MockRestServiceServer
. To do that, you have to use the following annotations for your test:And then you'll have to autowire your controller and
MockRestServiceServer
, for example:And now you can write tests like this:
In addition to testing that your actual REST call matches, this also allows you to test if your JSON-to-DTO works as well.
You can achieve this by using
@RestClientTest
andMockRestServiceServer
. An example provided in their documentation: