Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I mock a REST template exchange?

I have a service in which I need to ask an outside server via rest for some information:

public class SomeService {      public List<ObjectA> getListofObjectsA() {         List<ObjectA> objectAList = new ArrayList<ObjectA>();         ParameterizedTypeReference<List<ObjectA>> typeRef = new ParameterizedTypeReference<List<ObjectA>>() {};         ResponseEntity<List<ObjectA>> responseEntity = restTemplate.exchange("/objects/get-objectA", HttpMethod.POST, new HttpEntity<>(ObjectAList), typeRef);         return responseEntity.getBody();     } } 

How can I write a JUnit test for getListofObjectsA()?

I have tried with the below:

@RunWith(MockitoJUnitRunner.class) public class SomeServiceTest {     private MockRestServiceServer mockServer;      @Mock     private RestTemplate restTemplate;      @Inject    private SomeService underTest;  @Before public void setup() {     mockServer = MockRestServiceServer.createServer(restTemplate);     underTest = new SomeService(restTemplate);     mockServer.expect(requestTo("/objects/get-objectA")).andExpect(method(HttpMethod.POST))             .andRespond(withSuccess("{json list response}", MediaType.APPLICATION_JSON)); }      @Test     public void testGetObjectAList() {     List<ObjectA> res = underTest.getListofObjectsA();     Assert.assertEquals(myobjectA, res.get(0)); } 

However the above code does not work, it shows that responseEntitty is null. How can I correct my test to properly mock restTemplate.exchange?

like image 386
Akka Jaworek Avatar asked Sep 14 '16 09:09

Akka Jaworek


People also ask

Can we mock rest template?

We can use Mockito to mock the RestTemplate altogether. With this approach, testing our service would be as simple as any other test involving mocking. In the above JUnit test class, we first asked Mockito to create a dummy RestTemplate instance using the @Mock annotation.

How do you use RestTemplate getForObject?

Spring RestTemplate – HTTP GET Example getForObject(url, classType) – retrieve a representation by doing a GET on the URL. The response (if any) is unmarshalled to given class type and returned. getForEntity(url, responseType) – retrieve a representation as ResponseEntity by doing a GET on the URL.

How do you mock an external service?

To mock the external service, we can abstract all its logic within an interface which we can implement elsewhere and use it by our functional tests, returning the outcome we need to test the behavior of our application.


2 Answers

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));     } 
like image 142
Mindaugas Avatar answered Sep 21 '22 18:09

Mindaugas


This is an example with the non deprecated ArgumentMatchers class

when(restTemplate.exchange(                 ArgumentMatchers.anyString(),                 ArgumentMatchers.any(HttpMethod.class),                 ArgumentMatchers.any(),                 ArgumentMatchers.<Class<String>>any()))              .thenReturn(responseEntity); 
like image 45
itstata Avatar answered Sep 20 '22 18:09

itstata