蘑菇街支付金融Android單元測試實踐(2)

發表于:2016-05-20來源:推酷作者:不詳點擊數: 標簽:單元測試
這里的loadData()方法是void的,它該怎么測試呢?一個最直接的反應可能是,調用loadData()方法(當然,實際可能是通過其他事件觸發),然后一段時間后,驗證界

  這里的loadData()方法是void的,它該怎么測試呢?一個最直接的反應可能是,調用loadData()方法(當然,實際可能是通過其他事件觸發),然后一段時間后,驗證界面得到了更新。然而這種方法是錯的,這種測試叫集成測試,而不是單元測試。因為它涉及到很多個方面,它涉及到 DataModel、網絡服務器,以及網絡返回正確時,DataActivity內部的處理,等等。集成測試固然有它的必要性,但不是我們應該最關注的地方,也不是最有價值的地方。我們應該最關注的是單元測試。關于這一點,有一個 Test Pyramid 的理論:

  Test Pyramid理論基本大意是,單元測試是基礎,是我們應該花絕大多數時間去寫的部分,而集成測試等應該是冰山上面能看見的那一小部分。

  那么對于這個case,正確的單元測試方法,應該是去驗證loadData()方法調用了DataModel的某個請求數據的方法,同時傳遞的參數是正確的。“調用了DataModel的方法,同時參數是。。。” 這個才是loadData()這個方法的“返回結果”。

  Mock的概念以及Mockito框架

  要驗證某個對象的某個方法得到調用了,就涉及到mock的使用。這里對mock的概念做個簡單介紹,以免很多同學不熟悉,mock就是創建一個虛假的、模擬的對象。在測試環境下,用來替換掉真實的對象。這樣就能達到兩個目的:

  可以隨時指定mock對象的某個方法返回什么樣的值,或執行什么樣的動作。

  可以驗證mock對象的某個方法有沒有得到調用,或者是調用了多少次,參數是什么等等。

  要使用mock,一般需要使用mock框架,目前安卓最常用的有兩個, Mockito 和 JMockit 。兩者的區別是,前者不能mock static method和final class、final method,后者可以。我們依然采用的是Mockito,原因說起來慚愧,是因為剛開始并不知道JMockit這個東西,后來查了一些資料,看過很多 對比Mockito和JMockit的文章 ,貌似大部分還是很看好JMockit的,只是有一個問題,那就是跟robolectric的結合也有一些bug,同時使用姿勢跟Mockito有較大的不同,因此一直沒有抽時間去實踐過。這個希望以后能夠做進一步的調查,到時候在給大家分享一下使用感受。

  但是使用Mockito,就有一個問題,那就是static method和final class、final method沒有辦法mock,對于這點如何解決,我們稍后會介紹到。

  在測試環境中使用mock:依賴注入

  接下來的一個問題就是,如何在測試環境下,把DataModel換成mock的對象,而正式代碼中,DataModel又是正常的對象呢?

  這個問題也有兩種解決方案,一是使用專門的testing product flavor;二是使用依賴注入。第一種方案就是用一個專門的product flavor來做testing,在這個testing flavor里面,里面把需要mock的類寫一份mock的implementation,然后通過factory提供給client,這個 factory的接口在testing flavor和正式的flavor里面是一樣的,在跑testing的時候,專門使用這個testing flavor,這樣通過factory得到的就是mock的類。這種情況看起來很簡單,但其實很不靈活,因為只有一種mock實現;此外,代碼會變得很丑陋,因為你需要為每一個dependency提供一個factory,會覺得很刻意;再者,多了一個flavor,很多gradle任務都會變得很慢。關于這種方案,可以參考 這個視頻 (https://www.youtube.com/watch?v=vdasFFfXKOY)。

  因此,我們用的是第二種,依賴注入。先簡單介紹一下依賴注入這個模式,他的基本理念是,某一個類(比如說DataActivity),用到的內部對象(比如說DataModel)的創建過程不在DataActivity內部去new,而是由外部去創建好DataModel的實例,然后通過某種方式set給 DataActivity。這種模式應用是非常廣泛的,尤其是在測試的時候。為了更方便的做依賴注入,如今有很多框架專門做這件事情,比如 RoboGuice 、 Dagger 、 Dagger2 等等。我們用的是Dagger2,理由很簡單,這是目前最好用的DI框架。

  關于Dagger2的文章,之前我們群里也分享了不少,但是好像我并沒有看到講述沒有關于如何在測試環境下使用Dagger2的文章,這個還是略感遺憾的。離開單元測試,使用依賴注入就少了很有說服力的一個理由。

  那么這里我就介紹一下,怎么樣把Dagger2應用到單元測試中。熟悉dagger2的童靴可能知道,Dagger2里面最關鍵的有兩個概念, Module 和 Component 。Module是負責生成諸如DataModel這樣被別人(比如DataActivity)使用的類的地方。用術語的話,被別人使用的類 DataModel叫Dependency,使用到了別的類的類DataActivity叫Client。而Component則是供Client使用 Dependency的統一接口。也就是說,DataActivity通過Component,來得到一份DataModel的實例。

原文轉自: http://www.infoq.com/cn/articles/mogujie-android-unit-testing

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97