解讀Android官方MVP項目單元測試(4)
發表于:2016-06-29來源:簡書作者:geniusmart點擊數:
標簽:單元測試
//執行獲取數據列表的方法,并在回調函數中進行斷言 mLocalDataSource.getTasks( new TasksDataSource.LoadTasksCallback() { @Override public void onTasksLoaded (ListTask tasks) { //斷言
mLocalDataSource.getTasks(
new TasksDataSource.LoadTasksCallback() {
@Override
public void onTasksLoaded(List<Task> tasks) {
assertNotNull(tasks);
assertTrue(tasks.size() >=
2);
boolean newTask1IdFound =
false;
boolean newTask2IdFound =
false;
for (Task task: tasks) {
if (task.getId().equals(newTask1.getId())) {
newTask1IdFound =
true;
}
if (task.getId().equals(newTask2.getId())) {
newTask2IdFound =
true;
}
}
assertTrue(newTask1IdFound);
assertTrue(newTask2IdFound);
}
@Override
public void onDataNotAvailable() {
fail();
}
});
}
最后來看看跟網絡請求相關的TasksRemoteDataSource的測試
Google并沒有對這個類本身進行測試,但是對其他層依賴網絡請求數據進行測試的場景做了支持。試想一下,通過上面的分析,我們知道View層是真刀真槍的在模擬用戶的操作進行測試,如果某個測試case需要發起網絡請求,此時我們不知道何時才能返回數據,且由于網絡狀況等原因可能導致請求失敗,種種不確定因素下,是不可能完成一個測試的,解決的辦法很簡單,就是對網絡請求進行Fake,這個類是FakeTasksRemoteDataSource
,原理便是當需要用到TasksRemoteDataSource時,不會真正使用該類,而是注入FakeTasksRemoteDataSource,返回事先定義好的數據。
為此,這個項目在項目結構和代碼方面提供了很多支撐,體現在:
-
提供了mock和prod兩種Flavors
-
兩種Flavor分別提供了Injection,注入Fake類或真實類
-
所有與網絡請求相關的測試代碼存放在androidTestMock下
總結:Model層的測試時而在androidTest寫UT,時而在test里寫,時而在androidTestMock里,有點精神分裂的感覺。但是,真的好清晰,看起測試的結構來非常舒服。
MVP的單元測試架構總結
通過這個例子,我們已經了解了MVP各層之間的職責以及對應的測試內容,接下來做個總結,首先看下MVP測試架構圖:
MVP測試架構圖
-
View層
-
職責:MVP模式下,View層終于揚眉吐氣了,View本身該做的事情都能做了,比如UI布局,數據渲染,點擊按鈕交互等等
-
測試方式:以正常小QA的測試思維方法,就可以來定義這一層的測試方式,測試過程中需要真機或模擬器,并做真實的操作。
-
測試選型:依賴于Android環境,用谷歌強大的Espresso+AndroidJUnitRunner,Espresso用于模擬和驗證各種各樣的UI操作,代碼存放于AndroidTest中。
-
Presenter層:
-
職責:這一層是拉皮條的,負責M和V層的對接,所以有較少的處理輸入輸出的機會,他只用來控制邏輯,去調用相應的Model和View的邏輯。
-
測試選型:他的職責決定了他很少去斷言輸入輸出,測試邏輯覆蓋的路徑是否正確即可,因此他與Android環境無關,用Junit+Mockito測試即可,代碼存放于test中。
-
Model層