How to write mockito junit for Resttemplate exchange method

50.6k Views Asked by At

How to write mockito junit for the method below:

@Autowired
RestTemplate restTemplate;

ResponseEntity<?> execute(final String url, HttpMethod httpMethod,
                          HttpEntity<?> entityRequest,
                          String.class, 
                          Map<String, String> urlVariables){
    restTemplate.exchange(url, httpMethod, entityRequest, responseType, urlVariables);
}

Please help me how to write.

4

There are 4 best solutions below

0
On

It depends on what you want.

One way to use mocks is to make it easier to invoke the execute method. For that, you can use mocked versions of the actual parameters, such as the HttpMethod and the HttpEntity. If the underlying exchange method requires certain behavior from these parameters, you may need to stub that in with mockito's when ... thenReturn methods.

Once these mocked parameters are setup so that you can call your execute methods, you will want to check that its result is correct.

For checking the returned value, you can use traditional JUnit assertions.

Furthermore, you may want to check that certain interactions with the mocked objects actually took place. For that you can use mockito's verify methods to check, for example, that some HttpEntity method is actually invoked.

Technically, you could also verify that the rest template's exchange method is called. For that you'd need to mock the RestTemplate and inject the mock in you class under test. Then you can use mockito's verfiy to check that exchange is called in the proper way. This typically is the sensible thing to do, especially if there are more methods to test in your class-under-test. For the present execute method it seems a bit overkill though.

5
On
@RunWith(MockitoJUnitRunner.class)
public class ToTestTest {

  @InjectMocks
  private YourClass toTest;

  @Mock
  private RestTemplate template;

  @Test
  public void test() {
    toTest.execute(Mockito.anyString(), Mockito.any(), Mockito.any(), 
                   Mockito.any(), Mockito.any());

    Mockito.verify(template, Mockito.times(1))
                    .exchange(Mockito.anyString(),
                                    Mockito.<HttpMethod> any(),
                                    Mockito.<HttpEntity<?>> any(),
                                    Mockito.<Class<?>> any(),
                                    Mockito.<String, String> anyMap());
    }
 }
0
On

I used to get such an error. I found 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;

    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.

0
On

I think the most convenient and appropriate approach in this case (which is client side REST testing using RestTemplate) will be MockRestServiceServer provided by Spring Testing framework.