Serverless Unit Testing
The {@link oajr.mock.MockRest} class is a simple yet powerful interface for creating serverless
unit tests for your REST interfaces.
The following shows a self-encapsulated standalone JUnit testcase that tests the functionality of a simple REST interface.
public class MockTest {
// Our REST resource to test.
@RestResource(serializers=JsonSerializer.Simple.class, parsers=JsonParser.class)
public static class MyRest {
@RestMethod(name=PUT, path="/String")
public String echo(@Body String b) {
return b;
}
}
@Test
public void testEcho() throws Exception {
MockRest.create(MyRest.class).put("/String", "'foo'").execute().assertStatus(200).assertBody("'foo'"));
}
}
The API consists of the following classes:
- {@link oajr.mock}
- {@link oajr.mock.MockRest}
The API for instantiating mocks of REST resource classes.
- {@link oajr.mock.MockServletRequest}
An implementation of {@link javax.servlet.http.HttpServletRequest} with additional convenience methods for building requests.
- {@link oajr.mock.MockServletResponse}
An implementation of {@link javax.servlet.http.HttpServletRequest} with additional convenience methods for testing responses.
The concept of the design is simple. The {@link oajr.mock.MockRest} class is used to create instances of {@link oajr.mock.MockServletRequest}
and {@link oajr.mock.MockServletResponse} which are passed directly to the call handler on the resource class {@link oajr.RestCallHandler#service(HttpServletRequest,HttpServletResponse)}.
Breaking apart the fluent method call above will help you understand how this works.
@Test
public void testEcho() throws Exception {
// Instantiate our mock.
MockRest mr = MockRest.create(MyRest.class);
// Create a request.
MockServletRequest req = mr.put("/String", "'foo'");
// Execute it (by calling RestCallHandler.service(...) and then returning the response object).
MockServletResponse res = req.execute();
// Run assertion tests on the results.
res.assertStatus(200);
res.assertBody("'foo'");
}
The {@link oajr.mock.MockRest} class provides the following methods for creating requests:
- {@link oajr.mock.MockRest}
- {@link oajr.mock.MockRest#request(String,String) request(String,String)}
- {@link oajr.mock.MockRest#request(String,String,Object) request(String,String,Object)}
- {@link oajr.mock.MockRest#get(String) get(String)}
- {@link oajr.mock.MockRest#put(String,Object) put(String,Object)}
- {@link oajr.mock.MockRest#post(String,Object) post(String,Object)}
- {@link oajr.mock.MockRest#delete(String) delete(String)}
- {@link oajr.mock.MockRest#options(String) options(String)}
The {@link oajr.mock.MockServletRequest} class provides default implementations for all the methods defined
on the {@link javax.servlet.http.HttpServletRequest} in addition to many convenience methods.
The following fluent convenience methods are provided for setting common Accept
and Content-Type
headers.
- {@link oajr.mock.MockServletRequest}
- {@link oajr.mock.MockServletRequest#json() json()}
- {@link oajr.mock.MockServletRequest#xml() xml()}
- {@link oajr.mock.MockServletRequest#html() html()}
- {@link oajr.mock.MockServletRequest#plainText() plainText()}
- {@link oajr.mock.MockServletRequest#msgpack() msgpack()}
- {@link oajr.mock.MockServletRequest#uon() uon()}
- {@link oajr.mock.MockServletRequest#urlEnc() urlEnc()}
- {@link oajr.mock.MockServletRequest#yaml() yaml()}
The following fluent convenience methods are provided for building up your request.
- {@link oajr.mock.MockServletRequest}
- {@link oajr.mock.MockServletRequest#header(String,Object) header(String,Object)}
- {@link oajr.mock.MockServletRequest#query(String,Object) query(String,Object}}
- {@link oajr.mock.MockServletRequest#formData(String,Object) formData(String,Object)}
- {@link oajr.mock.MockServletRequest#attribute(String,Object) attribute(String,Object)}
- {@link oajr.mock.MockServletRequest#body(Object) body(Object)}
Fluent setters are provided for all common request headers:
- {@link oajr.mock.MockServletRequest}
- {@link oajr.mock.MockServletRequest#accept(Object) accept(Object)}
- {@link oajr.mock.MockServletRequest#acceptCharset(Object) acceptCharset(Object)}
- {@link oajr.mock.MockServletRequest#acceptEncoding(Object) acceptEncoding(Object)}
- {@link oajr.mock.MockServletRequest#acceptLanguage(Object) acceptLanguage(Object)}
- ...
The {@link oajr.mock.MockServletResponse} class provides default implementations for all the methods defined
on the {@link javax.servlet.http.HttpServletResponse} in addition to many convenience methods.
- {@link oajr.mock.MockServletResponse}
- {@link oajr.mock.MockServletResponse#getBody() getBody()}
- {@link oajr.mock.MockServletResponse#getBodyAsString() getBodyAsString()}
- {@link oajr.mock.MockServletResponse#assertStatus(int) assertStatus(int)}
- {@link oajr.mock.MockServletResponse#assertBody(String) assertBody(String)}
- {@link oajr.mock.MockServletResponse#assertBodyContains(String...) assertBodyContains(String...)}
- {@link oajr.mock.MockServletResponse#assertBodyMatches(String) assertBodyMatches(String)}
- {@link oajr.mock.MockServletResponse#assertBodyMatchesRE(String) assertBodyMatchesRE(String)}
- {@link oajr.mock.MockServletResponse#assertHeader(String,String) assertHeader(String,String)}
- {@link oajr.mock.MockServletResponse#assertHeaderContains(String,String...) assertHeaderContains(String,String...)}
The {@link oajr.mock.MockRest} object can also be used with the {@link oajrc.RestClient} class to
perform serverless unit testing through the client API of REST resources.
This can be useful for testing of interface proxies against REST interfaces (described later).
The example above can be rewritten to use a mock as follows:
public class MockTest {
// Our REST resource to test.
@RestResource(serializers=JsonSerializer.Simple.class, parsers=JsonParser.class)
public static class MyRest {
@RestMethod(name=PUT, path="/String")
public String echo(@Body String b) {
return b;
}
}
@Test
public void testEcho() throws Exception {
MockRest mr = MockRest.create(MyRest.class);
RestClient rc = RestClient.create().mockHttpConnection(mr).build();
assertEquals("'OK'", rc.doPut("/String", "'OK'").getResponseAsString());
}
}
The {@link oajrc.RestClientBuilder#mockHttpConnection(MockHttpConnection)} method allows you to pass in a mocked
interface for creating HTTP requests through the client interface.
The method creates a specialized HttpClientConnectionManager
for handling requests by taking information on the
client-side request and populating the {@link oajr.mock.MockServletRequest} and {@link oajr.mock.MockServletResponse} objects
directly without involving any sockets.