gpt4 book ai didi

android - 在 Android 上模拟服务器结果(Wiremock、MockWebServer 等)

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:01:43 25 4
gpt4 key购买 nike

有没有人有关于记录服务器响应的完整和最新的教程或项目 - 根据需要获取和发布 header 并使用 wiremock 和/或 mockwebserver 回放它们?

我已经看过很多了

最佳答案

我已经在我当前的项目中实现了一个。首先,我创建了一个 MockHTTPDispatcher 类,它扩展了 OkHttp3 的 Dispatcher 类。这里的 Matcher 是从 Hamcrest 导入的。

public class MockHTTPDispatcher extends Dispatcher {

private Map<Matcher<RecordedRequest>, MockResponse> requestResponseMap;

public MockHTTPDispatcher() {
requestResponseMap = new HashMap<>();
}

public MockHTTPDispatcher mock(Matcher<RecordedRequest> matcher, MockResponse mockResponse) {
requestResponseMap.put(matcher, mockResponse);
return this;
}

@Override
public MockResponse dispatch(RecordedRequest recordedRequest) {
String recordedRequestPath = recordedRequest.getPath();
for (Matcher<RecordedRequest> mockRequest : requestResponseMap.keySet()) {
if (mockRequest.matches(recordedRequest)) {
MockResponse response = requestResponseMap.get(mockRequest);
return response;
}
}
//means unable to find path for recordedRequestPath
return new MockResponse().setResponseCode(404);
}

//you can also create a clear() method to clear the requestResponseMap if needed
}

然后,我创建了一个实现 TestRuleMockWebServerRule 类。这组代码将涵盖您想要设置标题和不想设置标题的情况。

public class MockWebServerRule implements TestRule {
public static final String DOMAIN = "localhost";
public static final int PORT = 4567;
private MockHTTPDispatcher mockHTTPDispatcher;
private MockWebServer mockWebServer;

public MockWebServerRule() {
mockWebServer = new MockWebServer();
mockHTTPDispatcher = new MockHTTPDispatcher();
mockWebServer.setDispatcher(mockHTTPDispatcher);
}

@Override
public Statement apply(Statement statement, Description description) {
return new MockHTTPServerStatement(statement);
}

public void mockResponse(String path, String httpMethod, int httpResponseCode, String response) throws Exception {
mockResponseWithHeaders(path, httpMethod, httpResponseCode, response, null);
}

public void mockResponseWithHeaders(String path, String httpMethod, int httpResponseCode,
String response, Headers headers) throws Exception {
mock(allOf(pathStartsWith(path), httpMethodIs(httpMethod)), httpResponseCode, response, headers);
}

public void mock(Matcher<RecordedRequest> requestMatcher, int httpResponseCode, String response, Headers headers) throws IOException {
MockResponse mockResponse = new MockResponse()
.setResponseCode(httpResponseCode)
.setBody(response);
if (headers != null)
mockResponse.setHeaders(headers);
mockHTTPDispatcher.mock(requestMatcher, mockResponse);
}

public MockHTTPDispatcher getDispatcher() {
return mockHTTPDispatcher;
}

//inner class for starting and shutting down localhost
private class MockHTTPServerStatement extends Statement {

private Statement base;

public MockHTTPServerStatement(Statement base) {
this.base = base;
}

@Override
public void evaluate() throws Throwable {
mockWebServer.start(PORT);
try {
this.base.evaluate();
} finally {
mockWebServer.shutdown();
}
}
}
}

对于 httpMethodIspathStartsWith,您需要在某处创建这样的方法(我为这些创建了一个名为 RequestMatchers 的类)。

    public static Matcher<RecordedRequest> httpMethodIs(final String httpMethod) {
return new TypeSafeMatcher<RecordedRequest>() {
@Override
protected boolean matchesSafely(RecordedRequest item) {
return httpMethod.equals(item.getMethod());
}

@Override
public void describeTo(org.hamcrest.Description description) {
description.appendText("getMethod should return");
}
};
}

    public static Matcher<RecordedRequest> pathStartsWith(final String path) {
return new TypeSafeMatcher<RecordedRequest>() {
@Override
protected boolean matchesSafely(RecordedRequest item) {
return item.getPath().startsWith(path);
}

@Override
public void describeTo(org.hamcrest.Description description) {
description.appendText("getPath should return");
}
};
}

在您的仪器测试中,您可以使用注释 @Rule 调用模拟网络服务器规则,就像这样:

public class YourActivityTest {

@Rule
public MockWebServerRule mockWebServerRule = new MockWebServerRule();

@Test
public void shouldHandleResponse200() throws Exception {
mockWebServerRule.mockResponse("/your/api/endpoint/", "GET", 200, readAsset("response_success.json"));

//your assertion here
}
}

您可以将 "GET" 更改为 "POST" 或任何其他具有预期状态代码响应的内容。不要忘记在代码中的某处添加 readAsset(String fileName) 的实现,这样它就可以读取您存储的 json Assets 。

关于android - 在 Android 上模拟服务器结果(Wiremock、MockWebServer 等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37915235/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com