I am using RestTemplate exchange HttpMethod.POST
method to POST to an endpoint. In my test file I am testing for success
of the POST method. However with my current tests I am getting 401 Unauthorized error
when POST request is made. I need help to Mock the API while making POST request in test file
Here is my main file
@Component
public class DataTestRepo {
private final RestTemplate restTemplate;
private final String url;
private final AllBuilder headersBuilder;
public DataTestRepo(
@Qualifier(Oauth.BEAN_NAME) AllBuilder headersBuilder,
RestTemplate restTemplate, String url) {
this.headersBuilder = headersBuilder;
this.restTemplate = restTemplate;
this.url = url;
}
public ResponseEntity<String> postJson(Set<String> results) {
ResponseEntity<String> result = null;
try {
JSONObject jsonObject = new JSONObject(body);
HttpEntity<String> request = new HttpEntity<String>(jsonObject.toString(), null);
restTemplate.getMessageConverters().add(stringConvertor);
result = restTemplate.exchange(url, HttpMethod.POST,
new HttpEntity<>(request, getHttpHeaders()), String.class);
}
return result;
}
}
Here is my test file
@RunWith(MockitoJUnitRunner.class)
@TestPropertySource
public class DataTestRepoTest {
private static final String url = "http://localhost:8080/data/name";
@Mock
private DataTestRepo DataTestRepo;
RestTemplate restTemplate = new RestTemplate();
@Test
public void restTemplateHttpPost_success() throws URISyntaxException {
URI uri = new URI(url);
Set<String> mockData = Stream.of("A","B").collect(Collectors.toSet());
Map<String, String> body = new HashMap<>();
body.put("Name", "Aws");
JSONObject jsonObject = new JSONObject(body);
HttpEntity<String> request = new HttpEntity<>(jsonObject.toString(), null);
ResponseEntity<String> result = restTemplate.exchange(uri, HttpMethod.POST,
new HttpEntity<>(request, DataTestRepo.getHttpHeaders()), String.class);
Assert.assertEquals(201, result.getStatusCodeValue());
}
}
You are testing the logic inside DataTestRepo class, so you should not mock it. RestTemplate is a dependency inside DataTestRepo, so this is exactly what you need to mock. In general it should look like this inside your test:
@InjectMocks
private DataTestRepo DataTestRepo;
@Mock
RestTemplate restTemplate;
Also, you will have to provide a return value for your mocked dependency, like this:
Mockito.when(restTemplate.exchange(ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any())).thenReturn(new ResponseEntity<>(yourExpectedDataHere, HttpStatus.OK));
enter code here
This is just a simple example. A good practice would be to check that the arguments passed to your mock equal to the expected ones. One way would be to replace ArgumentMatchers.any() with the real expected data. Another is to verify it separately, like this:
Mockito.verify(restTemplate, Mockito.times(1)).exchange(ArgumentsMatchers.eq(yourExpectedDataHere), ArgumentsMatchers.eq(yourExpectedDataHere), ArgumentsMatchers.eq(yourExpectedDataHere), ArgumentsMatchers.eq(yourExpectedDataHere));