If you want to
create a mock Http server for integration testing to mock external
URLS/Servers. Here is the solution for java.
I have gone through
the all options like WireMock, nanoHttpd,Mock-Server,LightWeightServer…etc but
not full fill my requirements and not easy to use for my use case.
I created my own
solution for this problem and of course inspired from other blogs to get into
this .
First use
Dependencies:
testCompile
group: 'org.mortbay.jetty', name: 'jetty', version: '7.0.0.pre5'
compile
'commons-io:commons-io:2.5'
Mortbay Jetty will
do simple and nice job here.
If you’re working with webserver
clients you will certainly have noticed the difficulty in integration-testing
your webserver clients. Building webserver clients can already be quite a
complex task, but providing a mock-up webservice backend delivering useful test
responses is quite often just to much work, if not impossible, since many web
server backends are very complex constructs. Furthermore, setting up a backend
for each integration test consumes valuable build time.
As an alternative, one may simply replace
the backend with a mock HTTP server that does one thing: deliver the expected
webserver response – i.e. XML data – when called by the client. All
you need to set this up is a HTTP server and a pre-recorded service response
(quite often this comes with WS client specifications). If you don’t have this
data, you can record it, for example using a proxy server in between your WS
client and a real WS backend, or a tool such as wireshark.
The recorded XML response thus
represents your assumptions against which you test the client. This makes your
tests fast, lightweight and a lot better to understand.
Server Code Here
package com.java.testing.httpclient; import static javax.servlet.http.HttpServletResponse.SC_OK; import static org.apache.commons.io.IOUtils.write; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.IOUtils; import org.apache.http.entity.ContentType; import org.junit.Ignore; import org.mortbay.jetty.Handler; import org.mortbay.jetty.HttpConnection; import org.mortbay.jetty.Request; import org.mortbay.jetty.Server; import org.mortbay.jetty.handler.AbstractHandler; import com.touchpeak.restclient.util.NullUtil; /** * Used for Mocking Http Server * * @author Kumar * */ @Ignore public class MockHttpTestServer { private int HTTP_PORT = 55556; private Server _server; private String _responseBody; private String _requestBody; private String _mockResponseData; private Integer _mockResponseStatus; private String _mockResponseContentType; private String _requestPath; private String _requestMethod; private MaprequestedQueryParams = new HashMap<>(); public MockHttpTestServer() { } public MockHttpTestServer(int port) { HTTP_PORT = port; } public MockHttpTestServer(String mockData) { setMockResponseData(mockData); } public void start() throws Exception { configureServer(); startServer(); } private void startServer() throws Exception { _server.start(); } protected void configureServer() { _server = new Server(HTTP_PORT); _server.setHandler(getMockHandler()); } /** * Creates an {@link AbstractHandler handler} returning an arbitrary String * as a response. * * @return never null
. */ public Handler getMockHandler() { Handler handler = new AbstractHandler() { public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException { cleanInMemory(); Request baseRequest = request instanceof Request ? (Request) request : HttpConnection.getCurrentConnection().getRequest(); setRequestMethod(baseRequest.getMethod()); setRequestPath(baseRequest.getUri().getPath()); setResponseBody(getMockResponseData()); setRequestBody(IOUtils.toString(baseRequest.getInputStream(), "UTF-8")); response.setStatus(getMockResponseStatus()); response.setContentType(getMockResponseContentType() != null ? getMockResponseContentType() : "text/plain"); write(getResponseBody(), response.getOutputStream(), "UTF-8"); baseRequest.setHandled(true); } }; return handler; } protected void cleanInMemory() { setRequestBody(""); setRequestPath(""); } public void stop() throws Exception { _server.stop(); } public void setResponseBody(String responseBody) { _responseBody = responseBody; } public String getResponseBody() { return _responseBody; } public void setRequestBody(String requestBody) { _requestBody = requestBody; } public String getRequestBody() { return _requestBody; } public static void main(String[] args) { MockHttpTestServer server = new MockHttpTestServer(); try { server.start(); } catch (Exception e) { throw new RuntimeException(e); } } public void setMockResponseData(String mockResponseData) { _mockResponseData = mockResponseData; } public String getMockResponseData() { return _mockResponseData; } protected Server getServer() { return _server; } public MapgetRequestedQueryParams() { return requestedQueryParams; } public String getRequestPath() { return _requestPath; } public String getMockResponseContentType() { return _mockResponseContentType; } public void setMockResponseContentType(String _mockResponseContentType) { this._mockResponseContentType = _mockResponseContentType; } public Integer getMockResponseStatus() { return NullUtil.isNullOrEmpty(_mockResponseStatus) ? SC_OK : _mockResponseStatus; } public void setMockResponseStatus(Integer _mockResponseStatus) { this._mockResponseStatus = _mockResponseStatus; } public void setRequestPath(String _requestPath) { this._requestPath = _requestPath; } public String getRequestMethod() { return _requestMethod; } public void setRequestMethod(String _requestMethod) { this._requestMethod = _requestMethod; } }
Client Code Here
package com.java.testing.httpclient; import static org.junit.Assert.assertEquals; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.touchpeak.restclient.test.MockHttpTestServer; public class HttpClientTests { private static final Logger logger = LoggerFactory .getLogger(HttpClientTests.class); private MockHttpTestServer server; private String HOST = "127.0.0.1"; private int PORT =56342; private String TEST_BASE_URI = "http://"+HOST+":"+PORT; @Before public void init() { server = new MockHttpTestServer(PORT); try { server.start(); } catch (Exception e) { logger.error(" While starting Mock Http Server ",e); } } @After public void close() { try { server.stop(); } catch (Exception e) { logger.error(" While stopping Mock Http Server ",e); } } @Test public void test_Server_Call() { String mockResponse = "Mock Response you expect from server"; String mockRequestBody ="RequestBody Sent to server from client"; server.setMockResponseData(mockResponse); //Server will return above expected responses to client call. String actualResponse = " write client code here to call server and get the response from server call"; assertEquals("GET", server.getRequestMethod());//Check HTTP METHOD here assertEquals("/order/3?area=LONDON", server.getRequestPath());// Check Request URI assertEquals(mockRequestBody, server.getRequestBody());//Check RequestBody received by Server assertEquals(mockResponse, actualResponse);//check Response from server } }Tips: 1. you can also add Listeners to Server class to get control back on client side while executing.
No comments:
Post a Comment
Please comment here