使用Robolectric测试okHttp请求 - 回调

vki*_*ins 5 android robolectric android-testing

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

    ShadowLooper.pauseMainLooper();
    Robolectric.flushBackgroundScheduler();
    ShadowLooper.unPauseMainLooper();
Run Code Online (Sandbox Code Playgroud)

但那没用.有什么建议?

编辑:

这是我的代码示例:

ApiClient.sendSomeDataToServer(data, callback);
Run Code Online (Sandbox Code Playgroud)

其中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);
}
Run Code Online (Sandbox Code Playgroud)

其中sHttpClient是初始化的OkHttpClient.

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

Eug*_*nov 6

让我们假设您有下一个代码.接口:

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

执行:

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);
}
Run Code Online (Sandbox Code Playgroud)

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

public void fetchData(ClientInterface clients) {
}
Run Code Online (Sandbox Code Playgroud)

在这篇文章非常简单之后:

@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
}
Run Code Online (Sandbox Code Playgroud)

使用的模拟和验证库是Mockito.

由于泛型,将有一个警告与captor实例化,但如果您将使用@Captor注释而不是手工创建captor,则它可以修复.

参数注入并不完美,特别是对于活动情况.这用于简化示例.考虑正确注入库或不使用库.我鼓励你尝试Dagger注射