Created
May 6, 2017 19:31
-
-
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/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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