2015-07-03 101 views
3

我正在開發基於MVP模式的應用程序,使用改進來執行聯網。我想單元測試我的演示者,但它失敗了。包含Retrofit測試MVP Android

在我的應用程序dataView implements DataView這是由Mockito嘲笑。 DataPresenter in onViewCreated方法MyApi實例從MyApplication得到並執行請求。匿名Subscriber<Data> on下一個呼籲showData(Data data)dataView。不幸Mockito.verify(dataView).showData(data)未通過測試。我以自己的方式嘲笑改造客戶以確定性方式迴應。下面

代碼:

public class DataFragment extends ProgressFragment implements DataView { 

    protected DataPresenter mDataPresenter; 

    //[...] initialization arguments boilerplate etc. 


    @Override 
    public void onViewCreated(View view, Bundle savedInstanceState) { 
     super.onViewCreated(view, savedInstanceState); 
     mDataPresenter.onViewCreated(mId); 
     //[...] 
    } 

    @Override 
    public void startLoading() { 
     setContentShown(false); 
    } 

    @Override 
    public void stopLoading() { 
     setContentShown(true); 
    } 

    @Override 
    public void showData(Data data) { 
     setContentEmpty(false); 
     //[...] present data 
    } 

    @Override 
    public void showError() { 
     setContentEmpty(true); 
     setEmptyText(R.string.unknown_error); 
    } 
} 

DataPresenter

@Override 
public void onViewCreated(long id) { 
    getView().startLoading(); 
    MyApplication.getInstance().getMyApi().checkIn(User.getUser().getFormattedTokenForRequest(), 
      (int) id).observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).subscribe(new Subscriber<Data>() { 
     @Override 
     public void onCompleted() { 

     } 

     @Override 
     public void onError(Throwable e) { 
      getView().showError(); 
      getView().stopLoading(); 
     } 

     @Override 
     public void onNext(Data data) { 
      getView().showData(data); 
      getView().stopLoading(); 

     } 
    }); 
    ; 
} 

我的測試用例: dataView.showData(:

public static final String GOOD_RESPONSE = "[Data in JSON]" 
    public static final int GOOD_STATUS = 201; 

    @Mock 
    DataView mDataView; 

    @Mock 
    MyApplication app; 

    @Mock 
    SharedPreferencesManager mSharedPreferencesManager; 

    DataPresenter mDataPresenter; 

    @Before 
    public void setUp() throws Exception { 
     mDataPresenter = new DataPresenterImpl(mDataView); 
     MyApplication.setInstance(app); 
     Mockito.when(app.getSharedPreferencesManager()).thenReturn(mSharedPreferencesManager); 
     Mockito.when(mSharedPreferencesManager.getUser()).thenReturn(null); 
    } 

    @Test 
    public void testCase() throws Exception { 
     RestAdapter adapter = (new RestAdapter.Builder()).setEndpoint(URL) 
       .setClient(new MockClient(GOOD_RESPONSE, GOOD_STATUS)) 
       .build(); 
     Mockito.when(app.getMyApi()).thenReturn(adapter.create(MyApi.class)); 
     mCheckInPresenter.onViewCreated(3); 
     Mockito.verify(checkInView).startLoading(); 
     Mockito.verify(checkInView).showData(new Data()); 
    } 

測試的「通緝令,但不會調用失敗。 ..「。

有趣的是Response execute()被稱爲MockClient,但DataPresenterImpl包含的用戶onNext(Data data)不是。有任何想法嗎?我想這是一個請求異步的問題。

+0

@Mock SchedulerFactory factory @Before public void setUp() { when(factory.io()).thenReturn(Schedulers.mainThread()); } 

更感興趣的是驗證View是顯示數據還是你的網絡邏輯有效?一個人不必依賴另一個,並且可以在沒有任何視圖的情況下測試演示者的聯網邏輯。 –

回答

0

問題是,工作正在發送到不同的線程和mockito無法驗證發生了什麼事情。我的解決方案是創建一個調度程序工廠並將其模擬出來,並返回主線程,以便像這樣測試 。喜歡的東西:

public class schedulerFactory { 

public Scheduler io() { 
return Schedulers.io(); 
} 
//etc 
} 

然後在您的測試,你會寫是這樣的:在一般它是一個好主意,運行在同一個線程的所有代碼的測試