package com.github.ggeorgovassilis.springjsonmapper.support; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.ClientHttpResponse; /** * Factory for requests and responses that can be inspected and instrumented for tests * @author George Georgovassilis * */ public class MockRequestFactory implements ClientHttpRequestFactory { public class MockResponse implements ClientHttpResponse { ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]); HttpHeaders headers = new HttpHeaders(); HttpStatus status = HttpStatus.OK; { headers.add("Content-Type", "application/json"); } public void setStatus(HttpStatus status) { this.status = status; } public void setBody(byte[] bytes) { bais = new ByteArrayInputStream(bytes); } @Override public InputStream getBody() throws IOException { return bais; } @Override public HttpHeaders getHeaders() { return headers; } @Override public HttpStatus getStatusCode() throws IOException { return status; } @Override public int getRawStatusCode() throws IOException { return status.value(); } @Override public String getStatusText() throws IOException { return status.name(); } @Override public void close() { try { bais.close(); } catch (IOException e) { throw new RuntimeException(e); } } } public class MockRequest implements ClientHttpRequest { private URI uri; private HttpMethod method; private HttpHeaders headers = new HttpHeaders(); private ByteArrayOutputStream baos = new ByteArrayOutputStream(); private MockResponse response; public MockRequest(URI uri, HttpMethod method) { this.uri = uri; this.method = method; } public void setRespose(MockResponse response) { this.response = response; } @Override public HttpMethod getMethod() { return method; } @Override public URI getURI() { return uri; } @Override public HttpHeaders getHeaders() { return headers; } @Override public OutputStream getBody() throws IOException { return baos; } @Override public ClientHttpResponse execute() throws IOException { return response; } public String serializeToString() { StringBuffer sb = new StringBuffer(); sb.append(method.name() + " " + uri.toASCIIString() + "\n"); List<String> headerNames = new ArrayList<>(headers.keySet()); Collections.sort(headerNames); for (String header : headerNames) { sb.append(header + "="); String prefix = ""; for (String value : headers.get(header)) { sb.append(prefix + value); prefix = ","; } sb.append("\n"); } sb.append("\n"); try { sb.append(baos.toString("UTF-8")); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } return sb.toString(); } } private ThreadLocal<MockRequest> lastRequest = new ThreadLocal<MockRequestFactory.MockRequest>(); private ThreadLocal<MockResponse> response = new ThreadLocal<MockRequestFactory.MockResponse>(); @Override public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException { lastRequest.set(new MockRequest(uri, httpMethod)); lastRequest.get().setRespose(response.get()); return lastRequest.get(); } public void setResponse(MockResponse response) { this.response.set(response); } public MockRequest getLastRequest() { return lastRequest.get(); } public MockResponse createResponse() { response.set(new MockResponse()); return response.get(); } }