2015-03-31 93 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