2015-03-31 60 views
5

我有一个函数,我想测试哪些在okHttp回调中运行。我正在尝试使用Robolectrics进行测试,但回调从未执行过。我认为这是因为测试在请求之后继续而不等待okHttp返回。到目前为止,我已经尝试过:使用Robolectric测试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)并提供自定义回调来测试上述的执行情况。我试图测试的代码在回调中。任何建议如何我可以测试?我真的不想改变主代码以适应测试框架 - 应该是相反的。

+0

你使用任何依赖注入? – 2015-04-01 09:15:32

回答

5

让我们假设你有下一个代码。接口:

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

实施:

所有你需要改变 service实例化 service注射(如参数或字段)的
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); 
} 

第一。我会做它作为参数:

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注释而不是手动创建捕获器,则它是可修复的。

参数注入并不完美,特别是对于活动的情况。这被用来简化示例。考虑适当注入库还是不注册。我鼓励你试用Dagger进行注射

+0

这是没有Mockito可行的 - 只是与Robolectric? – vkislicins 2015-04-07 19:24:42

+0

当然可以。您可以编写自己的'ClientInterface'实现,您可以从方法中捕获回调并在测试中使用它。但是,如果'Mockito'已经为你提供它,为什么要写自己的类 – 2015-04-08 12:15:07

+0

不是基于ArgumentCaptor的整个解决方案,它是Mockito的一部分吗?这不是那个在执行和回调之间陷入困境的人吗? – vkislicins 2015-04-08 13:11:28