android - 使用 Robolectric 测试 okHttp 请求 - 回调

标签 android robolectric android-testing

我有一个要测试的函数,它在 okHttp 回调中运行。我正在尝试使用 Robolectrics 对其进行测试,但从未执行过回调。我认为这是因为测试在请求后继续进行而不等待 okHttp 返回。到目前为止,我已经尝试过:

    ShadowLooper.pauseMainLooper();
    Robolectric.flushBackgroundScheduler();
    ShadowLooper.unPauseMainLooper();

但这没有用。有什么建议吗?

编辑:

这是我的代码示例:

ApiClient.sendSomeDataToServer(data, callback);

其中 ApiClient 是一个包含 okHttp 客户端的辅助类。 sendSomeDataToServer API 调用看起来像这样:

public static void sendSomeDataToServer(MyObject data, Callback callback){
    final Request request = new Request.Builder()
            .url(API_SOME_URL)
            .post(RequestBody.create(JSON, myObject.getAsJson().toString()))
            .build();
    sHttpClient.newCall(request).enqueue(callback);
}

其中 sHttpClient 是一个初始化的 OkHttpClient。

我可以通过在我的测试代码中强制执行 Thread.sleep(5000) 并提供自定义回调来测试上面的执行。我要测试的代码在回调中。有什么建议我可以测试吗?我真的不想更改主要代码以适应测试框架 - 应该反过来。

最佳答案

假设您有下一个代码。界面:

@GET("/user/{id}/photo")  
void listUsers(@Path("id") int id, Callback<Photo> cb);

实现:

public void fetchData() {
    RestAdapter restAdapter = new RestAdapter.Builder()
                .setServer("baseURL")     
                .build();
    ClientInterface service = restAdapter.create(ClientInterface.class);

    Callback<Photo> callback = new Callback<Photo>() {
        @Override
        public void success(Photo o, Response response) {

        }

        @Override
        public void failure(RetrofitError retrofitError) {

        }
    };
    service.listUsers(435, callback);
}

首先,您需要将service 实例化更改为service 注入(inject)(作为参数或字段)。我将把它作为参数:

public void fetchData(ClientInterface clients) {
}

在这段文字非常琐碎之后:

@Test
public void checkThatServiceSuccessIsProcessed() {
    ClientInterface mockedClients = mock(ClientInterface.class);

    activity.fetchData(mockedClients);

    // get callback
    ArgumentCaptor<Callback<Photo>> captor = (ArgumentCaptor<Callback<Photo>>)ArgumentCaptor.forClass(Callback.class);
    verify(mockedInterface).listUsers(anything(), captor.capture());
    Callback<Photo> passedCallback = captor.value();
    // run callback
    callback.success(...);
    // check your conditions
}

用于模拟和验证的库是Mockito

由于泛型,捕获器实例化会出现一个警告,但如果您使用 @Captor 注释而不是手动创建捕获器,它是可以修复的。

参数注入(inject)并不完美,尤其是对于 Activity 的情况。这用于简化示例。考虑使用或不使用库进行正确注入(inject)。我鼓励您尝试使用 Dagger 进行注入(inject)

关于android - 使用 Robolectric 测试 okHttp 请求 - 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29374696/

相关文章:

android - 作为 UI 测试的一部分在 Application 类中进行的模拟 API 调用

android - NDK : Android. mk/GNU 制作

android - GridView 小部件中的重复项目

android - Robolectric 在某些情况下与 Android 数据绑定(bind)挂起

android - 为什么在使用 Robolectric 时不调用 PopupWindow.OnDismissListener?

java - 如何使用 VisibleForTesting 进行纯 JUnit 测试

java - 如何在android中获取rss feed

android - 使用 ORMLite 填充 ListView

android - 将 Robolectric 与 android.support.v7.app.MediaRouteButton 结合使用

android - gcloud CLI : How to run instrumentation tests with clearPackageData argument?