How to Mock a Rest Template Exchange

How do I mock a REST template exchange?

You don't need MockRestServiceServer object. The annotation is @InjectMocks not @Inject. Below is an example code that should work

@RunWith(MockitoJUnitRunner.class)
public class SomeServiceTest {
@Mock
private RestTemplate restTemplate;

@InjectMocks
private SomeService underTest;

@Test
public void testGetObjectAList() {
ObjectA myobjectA = new ObjectA();
//define the entity you want the exchange to return
ResponseEntity<List<ObjectA>> myEntity = new ResponseEntity<List<ObjectA>>(HttpStatus.ACCEPTED);
Mockito.when(restTemplate.exchange(
Matchers.eq("/objects/get-objectA"),
Matchers.eq(HttpMethod.POST),
Matchers.<HttpEntity<List<ObjectA>>>any(),
Matchers.<ParameterizedTypeReference<List<ObjectA>>>any())
).thenReturn(myEntity);

List<ObjectA> res = underTest.getListofObjectsA();
Assert.assertEquals(myobjectA, res.get(0));
}

How to mock a RestTemplate Exchange spring boot

The problem is resolved when I update the method to non static and move the Resttemplate declaration outside the method.

Updated code is below, if anyone found it useful.

Method changes :

public class Util{
private RestTemplate restTemplate= new RestTemplate();
public ResponseEntity<String> callRestService(JSONObject reqJsonObj,HttpHeaders headers, String url, HttpMethod method, boolean isAuto){
ResponseEntity<String> re=null;
try{
HttpEntity<String> entity=null;
entity=new HttpEntity<>(String.valueOf(reqJsonObj),headers);
re=restTemplate.exchange(url,method,entity,String.class);
}catch(Exception e){
System.out.println(e);
}
}
}

And the mock with verify :

public class UtilTest{
@InjectMocks
Util util;
@Mock
RestTemplate restTemplate;

@Test
public void test(){
ResponseEntity<String> entity=new ResponseEntity<String>("anySt",HttpStatus.ACCEPTED);
Mockito.when(restTemplate.exchange(
ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(HttpEntity.class),
ArgumentMatchers.<Class<String>>any())
).thenReturn(entity);

Util.callRestService(json,headers,url,HttpMethod.POST,false);

Mockito.verify(restTemplate,times(1)).exchange(
ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(HttpEntity.class),
ArgumentMatchers.<Class<String>>any())
)
}
}

How do i mock RestTemplate exchange

I used to get such an error. I figured out a more reliable solution. I have mentioned the import statements too which have worked for me. The below piece of code perfectly mocks the rest template.

import org.mockito.Matchers; 
import static org.mockito.Matchers.any;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;

This is the actual template to mock.

    HttpHeaders headers = new Headers();
headers.setExpires(10000L);
ResponseEntity<String> responseEntity = new ResponseEntity<>("dummyString", headers, HttpStatus.OK);
when(restTemplate.exchange( Matchers.anyString(),
Matchers.any(HttpMethod.class),
Matchers.<HttpEntity<?>> any(),
Matchers.<Class<String>> any())).thenReturn(responseEntity);

Here the 'responseEntity' value will not be null and we can use it to perfectly assert a statement.

Mock RestTemplate API call

You don't need a new RestTemplate every time you call the getAccessToken() method. It should instead be injected by Spring:

@Service
public class SnowFlakeService {

private RestTemplate restTemplate;

public ServiceImpl(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}

@Override
public String getAccessToken() {
try {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
httpHeaders.setBasicAuth(snowFlakeClientId, snowFlakeClientSecret);

MultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add("grant_type", snowFlakeRefreshTokenGrantType);
requestBody.add("refresh_token", refreshToken);
requestBody.add("redirect_uri", snowFlakeRedirectUrl);

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(requestBody, httpHeaders);
ResponseEntity<SnowFlakeTokenDTO> response = restTemplate.exchange(snowFlakeTokenRequestUrl, HttpMethod.POST, request, SnowFlakeTokenDTO.class);

return Objects.requireNonNull(response.getBody()).getAccessToken();
} catch (Exception e) {
throw new ErrorDTO(Status.BAD_REQUEST, accessTokenErrorMessage, e.getMessage());
}
}
}

On top of this, you don't actually need a @SpringBootTest in order to test SnowFlakeService. A regular unit test is pretty much ok.

public class SnowFlakeServiceTest {

private RestTemplate restTemplate = Mockito.mock(RestTemplate.class);
private SnowFlakeService snowFlakeService = new SnowFlakeService(restTemplate);

@Test
public void testGetAccessToken() {
SnowFlakeTokenDTO snowFlakeTokenDTO = new SnowFlakeTokenDTO();
snowFlakeTokenDTO.setAccessToken("fakeAccessToken");
snowFlakeTokenDTO.setExpiresIn(600);
snowFlakeTokenDTO.setTokenType("Bearer");

ResponseEntity<SnowFlakeTokenDTO> responseEntity = new ResponseEntity<>(snowFlakeTokenDTO, HttpStatus.OK);
when(restTemplate.exchange(
ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(),
ArgumentMatchers.<Class<SnowFlakeTokenDTO>>any()))
.thenReturn(responseEntity);

assertThat(snowFlakeService.getAccessToken()).isEqualTo(snowFlakeTokenDTO.getAccessToken());
}

}


Related Topics



Leave a reply



Submit