單元測試-mock使用應該注意什麼

yoylee_web發表於2019-01-18

系列導航

點選跳轉到系列博文目錄導航

概念

Mock的概念,其實很簡單:所謂的mock就是建立一個類的虛假的物件,在測試環境中,用來替換掉真實的物件,以達到兩大目的:

  • 驗證這個物件的某些方法的呼叫情況,呼叫了多少次,引數是什麼等等
  • 指定這個物件的某些方法的行為,返回特定的值,或者是執行特定的動作

上述兩大目的應該好好理解一下,理解了目的也就大致知道了何時使用mock

使用場景

  • 被測試物件依賴的物件構造複雜

比如:class A 依賴 class B、class B 依賴 class C和class D、class C 依賴 …、class D 依賴 …
此處我們想測試classA,在沒有mock的情況下就要去根據要求去構造classBCD等物件,耗時耗力。
在mock的情況下,我們可以直接mockclassBCD並通過設計其行為來實現測試classA的目的,因為我們只是想測試class A的行為是否符合預期,我們並不需要測試依賴物件。

  • 被測試單元所依賴的模組還沒有開發完成,而被測試物件需要需要依賴模組的返回值進行測試。也就是測試單元依賴了無法獲取的下游資料

比如:service中方法的測試需要dao中的訪問資料庫操作並獲取其返回值,但是我們還沒有開發完成對應的dao方法,我們就可以mock一個dao層的物件,將其行為設定為:當呼叫其中的某個方法時返回一個設定的值。
這樣我們對service的測試就可以不必受dao層的開發速度影響。也符合只對service方法邏輯進行測試。

原則

  • 不需要對所有的單元測試都將物件進行mock,只對上述使用場景介紹的相關場景使用mock。
  • 在分層測試中,高層的測試設計可以基於以下假設:底層的測試已保證底層物件的質量,高層無需關心低層物件的內部邏輯質量。這種情況下高層可以對低層物件進行mock。

常用框架

  • EasyMock : 早期比較流行的mock框架,它提供對介面的模擬,能夠通過錄制、回放、檢查三步來完成大體的測試過程,可以驗證方法的呼叫種類、次數、順序,可以令 Mock 物件返回指定的值或丟擲指定異常
  • Mockito:EasyMock之後流行的mock工具。相對EasyMock學習成本低,而且具有非常簡潔的API,測試程式碼的可讀性很高。
  • PowerMock:這個工具是在EasyMock和Mockito上擴充套件出來的,目的是為了解決EasyMock和Mockito不能解決的問題,比如對static, final, private方法均不能mock。

其實測試架構設計良好的程式碼,一般並不需要這些功能,但如果是在已有專案上增加單元測試,老程式碼有問題且不能改時,就不得不使用這些功能了。
PowerMock 在擴充套件功能時完全採用和被擴充套件的框架相同的 API, 熟悉 PowerMock 所支援的模擬框架的開發者會發現 PowerMock 非常容易上手。PowerMock 的目的就是在當前已經被大家所熟悉的介面上通過新增極少的方法和註釋來實現額外的功能。目前PowerMock 僅擴充套件了 EasyMock 和 mockito,需要和EasyMock或Mockito配合一起使用。

  • Jmockit:JMockit 是一個輕量級的mock框架是用以幫助開發人員編寫測試程式的一組工具和API,該專案完全基於 Java 5 SE 的 java.lang.instrument 包開發,內部使用 ASM 庫來修改Java的Bytecode。

Jmockit功能和PowerMock類似,某些功能甚至更為強大,但個人感覺其程式碼的可讀性並不強。

mock框架有好多,我們在選用mock框架時可以根據使用環境使用相對的mock框架,不過在正常情況下,個人感覺mockito還是不錯的:程式碼可讀性強,易於上手,功能絕大數專案的單元測試都夠用,不需要依賴其他元件。這或許也是mockito這麼流行的原因吧。

refer:部落格 部落格

如果轉載此博文,請附上本文連結,謝謝合作~ :https://blog.csdn.net/csdn___lyy

如果感覺這篇文章對您有所幫助,請點選一下“喜歡”或者“關注”博主,您的喜歡和關注將是我前進的最大動力!

相關文章