Skip to content

Instantly share code, notes, and snippets.

@alexshr
Created May 6, 2017 19:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexshr/033f8d639a448011bbf626cb836d76d4 to your computer and use it in GitHub Desktop.
Save alexshr/033f8d639a448011bbf626cb836d76d4 to your computer and use it in GitHub Desktop.
MockWebServer dispatcher supports requests plan, assert the request history, can take file for response from path/
package com.skb.goodsapp;
import android.util.Log;
import org.junit.Assert;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.RecordedRequest;
import static com.skb.goodsapp.AppConfig.LAST_MODIFIED_HEADER;
/** Created by alexshr
*
* MockWebServer dispatcher.
*
* It supports request plan:
* mMockDispatcher.setRequestPlan(products, 400, 400, 400, 200); - for 4 products requests
* response codes will be: 400, 400, 400, 200
*
* Then you can check the history of requests
* mMockDispatcher.assertRequestsHistory();
*
* Contains utility to get file from path
*
*/
public class MockDispatcher extends Dispatcher {
public static final String MOCK_RESP_GET_PRODUCTS_200 = "mock_responses/get_products_200.json";
public static final String MOCK_ERROR_400 = "mock_responses/error_400.json";
public static final String MOCK_RESP_POST_COMMENT_201 = "mock_responses/post_comment_201.json";
public static final String MOCK_RESP_POST_AVATAR_200 = "mock_responses/post_avatar_200.json";
public static final String MOCK_RESP_POST_LOGIN_200 = "mock_responses/post_login_200.json";
private static String LOG = MockDispatcher.class.getSimpleName();
public enum RequestPath {products, comments, avatar, login}
public static final String SERVER_LAST_MODIFIED_DATE = "Thu, 01 Jan 2017 00:00:00 GMT";
HashMap<RequestPath, ArrayDeque<Integer>> mResponsePlan = new HashMap<>();
public void setRequestPlan(RequestPath requestPath, int... respCodes) {
ArrayDeque<Integer> deque = new ArrayDeque<>();
for (int code : respCodes) {
deque.add(code);
}
mResponsePlan.put(requestPath, deque);
}
private RequestPath getRequestPath(RecordedRequest request) {
String path = request.getPath();
if (path.contains("?")) {
path = path.substring(0, path.indexOf("?"));
}
int pos = path.lastIndexOf("/");
path = path.substring(pos + 1);
return RequestPath.valueOf(path);
}
public void reset() {
mResponsePlan.clear();
}
@Override
public MockResponse dispatch(RecordedRequest request) throws InterruptedException {
Log.d(LOG, "dispatch request=" + request + " plan: " + toString());
RequestPath path = getRequestPath(request);
ArrayDeque<Integer> codes = mResponsePlan.get(path);
int code = codes.pop();
Log.d(LOG, "dispatch code=" + code);
if (codes.isEmpty()) mResponsePlan.remove(path);
return getMockResponse(request, code);
}
private MockResponse getMockResponse(RecordedRequest request, int code) throws InterruptedException {
MockResponse resp = new MockResponse();
resp.addHeader(LAST_MODIFIED_HEADER, SERVER_LAST_MODIFIED_DATE);
RequestPath path = getRequestPath(request);
try {
if (path == RequestPath.products && code == 200) {
return resp.setResponseCode(200)
.setBody(getStringFromFile(MOCK_RESP_GET_PRODUCTS_200));
} else if (path == RequestPath.comments && code == 201) {
return resp.setResponseCode(201)
.setBody(getStringFromFile(MOCK_RESP_POST_COMMENT_201));
} else if (path == RequestPath.avatar && code == 200) {
return resp.setResponseCode(200)
.setBody(getStringFromFile(MOCK_RESP_POST_AVATAR_200));
} else if (path == RequestPath.login && code == 200) {
return resp.setResponseCode(200)
.setBody(getStringFromFile(MOCK_RESP_POST_LOGIN_200));
} else if (code == 400) {
return resp.setResponseCode(400)
.setBody(getStringFromFile(MOCK_ERROR_400));
} else if (code == 403) {
return resp.setResponseCode(403);
} else if (code == 304) {
return resp.setResponseCode(304);
} else {
throw new IllegalArgumentException("unknown request or response code: request: " + request + " response code=" + code);
}
} catch (IOException e) {
throw new InterruptedException(e.toString());
}
}
//check requests against response plan
public void assertRequestsHistory() {
Assert.assertTrue("requests doesn't match response plan:" + toString(), mResponsePlan.isEmpty());
}
public String toString() {
StringBuilder b = new StringBuilder(this.getClass().getName() + " responsePlan: ");
Set rSet = mResponsePlan.entrySet();
Iterator<Map.Entry<RequestPath, Deque<Integer>>> iter = rSet.iterator();
while (iter.hasNext()) {
Map.Entry<RequestPath, Deque<Integer>> entry = iter.next();
b.append(entry.getKey().name() + "(");
for (Integer code : entry.getValue()) {
b.append(code + " ");
}
b.append(") ");
}
return b + "";
}
private static String convertStreamToString(InputStream is) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
}
public static String getStringFromFile(String filePath) throws IOException {
InputStream stream = MockDispatcher.class.getClassLoader().getResourceAsStream(filePath);
String res = convertStreamToString(stream);
stream.close();
return res;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment