5

サーバー応答の記録に関する完全かつ最近のチュートリアルまたはプロジェクトを持っている人はいますか?

私はすでにそこにたくさん見てきました

4

1 に答える 1

2

現在のプロジェクトで実装しました。まず、OkHttp3 からMockHTTPDispatcherクラスを拡張するクラスを作成しました。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
}

次に、をMockWebServerRule実装するクラスを作成しましたTestRule。この一連のコードは、ヘッダーを設定する場合と設定しない場合のケースをカバーします。

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();
            }
        }
    }
}

httpMethodIsとの場合、pathStartsWithこのようなメソッドをどこかに作成する必要があります (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インストルメンテーション テストでは、次のようにアノテーションを使用してモック Web サーバー ルールを呼び出すことができます。

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"with"POST"またはその他のものを、予想されるステータスコード応答で変更するだけです。コードのどこかに の実装を追加することを忘れないreadAsset(String fileName)でください。これにより、保存した json アセットを読み取ることができます。

于 2016-09-06T17:53:39.250 に答える