Android 测试中的模拟 Api 响应

问题描述 投票:0回答:4

我正在寻找一种在 Android 测试中模拟 api 响应的方法。

我已经读到机器人电动车可以用于此目的,但我真的很感激对此的任何建议。

android robolectric android-testing
4个回答
4
投票

在网上浏览了一会儿之后,我发现 MockWebServer 就是我正在寻找的东西。

用于测试 HTTP 客户端的可编写脚本的 Web 服务器。该库可以轻松测试您的应用程序在进行 HTTP 和 HTTPS 调用时是否执行正确的操作。它允许您指定要返回哪些响应,然后验证请求是否按预期发出。

要进行设置,只需将以下内容添加到您的 build.gradle 文件中。

androidTestCompile 'com.google.mockwebserver:mockwebserver:20130706'

这是一个取自他们的 GitHub 页面的简单示例。

public void test() throws Exception {
    // Create a MockWebServer. These are lean enough that you can create a new
    // instance for every unit test.
    MockWebServer server = new MockWebServer();

    // Schedule some responses.
    server.enqueue(new MockResponse().setBody("hello, world!"));

    // Start the server.
    server.play();

    // Ask the server for its URL. You'll need this to make HTTP requests.
    URL baseUrl = server.getUrl("/v1/chat/");

    // Exercise your application code, which should make those HTTP requests.
    // Responses are returned in the same order that they are enqueued.
    Chat chat = new Chat(baseUrl);

    chat.loadMore();
    assertEquals("hello, world!", chat.messages());

    // Shut down the server. Instances cannot be reused.
    server.shutdown();
  }

希望这有帮助。


4
投票

MockWebServer 不适用于我的 AndroidTestCase。例如,ECONNREFUSED 错误发生得相当随机(在https://github.com/square/okhttp/issues/1069中进行了描述)。我没有尝试过 Robolectric。

从 OkHttp 2.2.0 开始,我找到了一种对我来说效果很好的替代方法:拦截器。我将整个模拟响应放在存储在

androidTest/assets/
上的 json 文件中,例如“mock_response.json”。当我实例化 OkHttp 进行测试时,我公开了一个拦截器,我将重写传入的响应。基本上,body() 会在“mock_response.json”中传输数据。

public class FooApiTest extends AndroidTestCase {
    public void testFetchData() throws InterruptedException, IOException {
        // mock_response.json is placed on 'androidTest/assets/'
        final InputStream stream = getContext().getAssets().open("mock_response.json");

        OkHttpClient httpClient = new OkHttpClient();
        httpClient.interceptors().add(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                return new Response.Builder()
                        .protocol(Protocol.HTTP_2)
                        // This is essential as it makes response.isSuccessful() returning true.
                        .code(200)
                        .request(chain.request())
                        .body(new ResponseBody() {
                            @Override
                            public MediaType contentType() {
                                return null;
                            }

                            @Override
                            public long contentLength() {
                                // Means we don't know the length beforehand.
                                return -1;
                            }

                            @Override
                            public BufferedSource source() {
                                try {
                                    return new Buffer().readFrom(stream);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                    return null;
                                }
                            }
                        })
                        .build();
            }
        });

        FooApi api = new FooApi(httpClient);
        api.fetchData();

        // TODO: Let's assert the data here.
    }
}

1
投票

现在使用 Mockinizer 变得更加容易,这使得使用 MockWebServer 变得更容易:

val mocks: Map<RequestFilter, MockResponse> = mapOf(

    RequestFilter("/mocked") to MockResponse().apply {
        setResponseCode(200)
        setBody("""{"title": "Banana Mock"}""")
    },

    RequestFilter("/mockedError") to MockResponse().apply {
        setResponseCode(400)
    }

)

只需创建 RequestFilter 和 MockResponses 的映射,然后将其插入到您的 OkHttpClient 构建器链中:

OkHttpClient.Builder()
            .addInterceptor(loggingInterceptor)
            .mockinize(mocks) // <-- just plug in your custom mocks here
            .build()

0
投票

您应该尝试Beeceptor 的 HTTP 代理。它是一个托管的 HTTP 代理,可帮助您记录移动应用程序和服务器之间的流量,然后让您有选择地模拟一些/所有调用。这样您就可以根据自己的意愿打开或关闭确定性测试,并比较应用程序的行为。

我添加一个图像是为了快速了解它如何拦截来自移动应用程序的 HTTP 流量并为您提供查看和修改功能。

© www.soinside.com 2019 - 2024. All rights reserved.