2011年7月9日 星期六

使用 Mockito 更輕鬆地寫 unit test

vgod 提到可以用 PowerMock 來換掉 static、private、final 的方法,還有 Mockito 用起來很順手。於是大概看了一下相關文件:

我花了一些時間看了 Mockito 範例和作者設計的思路,覺得很有意思。 《behind the times: Mocks and Stubs aren't Spies》 提到在寫測試碼時,替換掉實際互動的元件,有四種不同層級的輔助元件: dummy、stub、spy、mock:

  • dummy: 什麼事也不做。
  • stub: 依據輸入傳回物件,藉此控制後續的邏輯。(相對來說) 不在意被呼叫的方式,像是何時被呼叫、呼叫了幾次等。
  • spy: 用來確認該物件如何被使用。比方說呼叫 cursor 物件的 commit() 前有沒有先呼叫 execute()。
  • mock: 同stub + spy,既需要傳回物件供待測方法使用,也在意它如何被呼叫。

寫測試碼常遇到的困擾是:mock 太囉唆了。這篇提供一個小例子對照 MockitoEasyMock 的差異。《should I worry about the unexpected?》 解釋 mock 之所以囉唆,是因為它管太多了,導致加新功能時,常常行為沒錯,卻無法通過舊的測試。使用 spy (Mockito 的主要功能) 就不會有這種困擾。大多情況我們並不在意是否每一個物件都要如預期般執行,只要關鍵的幾個步驟沒錯即可。

之前會排斥使用 mock 的原因為:

  1. 沒有和真正的物件互動,不夠踏實。
  2. 寫起來很囉唆。
  3. 囉唆就算了,稍微改改程式還很容易出錯。

第一點是 trade-off,有時候是不得不做的必要之惡。在看到 spy 的概念後,發覺它少了後兩項缺點。之後需要用到「mock」時,再來用 Mockito 看看。Mockito 另一個好處是,它有提供各種語言的版本,可以學一套語法走天下。