REST Client Testing With MockRestServiceServer

Published:
Reading time:
About 3 min

 

Functionally testing a REST Client is simple with the new MockRestServiceServer if you are using Spring’s RestTemplate to power the client. This is a new feature in Spring 3.2.x but was available via the spring-test-mvc project starting with Spring 3.1.x (extra spring-test-mvc.jar required). The documentation is a little light in the spring reference manual so hopefully this example can help you piece it together.

Previously you might have had unit tests that mocked the RestTemplate but didn’t fully test the calls and error handling provided with the framework. Or you created an elaborate fake server environment just to spit back valid and invalid responses. MockRestServiceServer takes the approach of mocking the server and allowing you to specify expected behavior and responses in your junit test class. This allows you to fully test your handling of the RestTemplate client and server exception classes.

This example only shows how the mock server works. In a real environment you’d probably use RestTemplate with Jackson for object to json mapping and possibly Spring @Async for asynchronous calls.

SimpleRestService is a sample REST client that makes a call to a URL and handles successes and errors by returning them in the result string. We'll use this as an example for our junit test cases:

@Service
      public class SimpleRestService {
      @Autowired
      private RestTemplate restTemplate;

public String getMessage() { String result; try { String httpResult = restTemplate.getForObject(“http://google.com”, String.class); result = "Message SUCCESS result: " + httpResult; } catch (HttpStatusCodeException e) { result = "Get FAILED with HttpStatusCode: " + e.getStatusCode() + “|” + e.getStatusText(); } catch (RuntimeException e) { result = “Get FAILEDn” + ExceptionUtils.getFullStackTrace(e); } return result; } }

The only real setup you need for testing is to configure your IDE to find the static imports. In Eclipse this is in Java>Editor>Content Assist>Favorites. Add these to go along with the hamcrest CoreMatchers and junit Assert that you probably already have.
If using Spring 3.2.x:
org.springframework.test.web.client.match.MockRestRequestMatchers
org.springframework.test.web.client.response.MockRestResponseCreators
If using Spring 3.1.x, the static import classes are named differently:
org.springframework.test.web.client.match.RequestMatchers
org.springframework.test.web.client.response.ResponseCreators

Each test will chain expect() and respond() methods. MockRestRequestMatchers offers many hamcrest matchers to check your request URL, headers, HTTP method, and even json and xpath matchers to check body content. MockRestResponseCreators allows you to easily build both success and error responses.

Also, each test must call mockServer.verify() after the RestTemplate call is made to run the Mock Server assertions.

Setup the MockRestServiceServer in the setUp method:

 @Before
public void setUp() {
mockServer = MockRestServiceServer.createServer(restTemplate);
}

testGetMessage() verifies our URL, GET HttpMethod, and returns a 200 Success with a text message of resultSuccess:

 @Test
public void testGetMessage() {
mockServer.expect(requestTo(“http://google.com”))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(“resultSuccess”, MediaType.TEXT_PLAIN));

String result = simpleRestService.getMessage();

mockServer.verify(); assertThat(result, allOf(containsString(“SUCCESS”), containsString(“resultSuccess”))); }

testGetMessage_404() shows a response with the specific 404 Not Found client http status code:

 @Test
public void testGetMessage_404() {
mockServer.expect(requestTo(“http://google.com”))
.andExpect(method(HttpMethod.GET))
.andRespond(withStatus(HttpStatus.NOT_FOUND));

String result = simpleRestService.getMessage();

mockServer.verify(); assertThat(result, allOf(containsString(“FAILED”), containsString(“404”))); }

testGetMessage_500() shows usage of the withServerError() convenience method:

 @Test
public void testGetMessage_500() {
mockServer.expect(requestTo(“http://google.com”))
.andExpect(method(HttpMethod.GET))
.andRespond(withServerError());

String result = simpleRestService.getMessage();

mockServer.verify(); assertThat(result, allOf(containsString(“FAILED”), containsString(“500”))); }

Additional matcher test examples can be found in the spring-test-mvc section of the spring 3.2.x github repo.

Hopefully the new mock server in Spring helps you as much as it helped me, by cleaning up and reducing the amount of testing code required in both a reusable and standard fashion. The full java code from these examples are on my github page.

Cross-published on the Object Partners blog: https://objectpartners.com/2013/01/09/rest-client-testing-with-mockrestserviceserver/