Mockito 如何 mock 返回值為 void 的方法


轉載:https://unmi.cc/mockito-how-to-mock-void-method/#more-7748

最初接觸 Mockito 還思考並嘗試過如何用它來 mock 返回值為 void 的方法,然而 Google 查找到的一般都會說用 doThrow() 的辦法

doThrow(new RuntimeException()).when(mockObject).methodWithVoidReturn();

因為無法使用常規的 when(mockObject.foo()).thenReturn(...) 的方法。

當時我就納悶,為何我想 mock 一個返回值為 void 的方法,卻是在模擬拋出一個異常,現在想來如果一個返回值為 void 的方法,為何要去 mock 這個方法呢?

回想一個我們要 mock 一個方法的意圖是什么:

  1. 在特定輸入參數的情況下期待需要的輸出結果(返回值)
  2. 在方法拋出某種類型異常調用者作出的反應

對於 void 返回值的方法,如果要驗證有沒有被調用過幾次可以在事后用 verify() 方法去斷言。所以基本上對於 void 返回值的方法一般可不用去 mock 它,只需用  verify() 去驗證,或者就是像前面一樣模擬出現異常時的情況。

所以本文並不像是去直接回答標題所示的問題: Mockito 如何 mock  返回值為  void 的方法,而是如何應對 mock  對象的  void 方法

一般不用對 void 方法打樁, 事后 verify 就行

測試代碼針對 mock  對象的 void 方法調用本來就沒有什么效果,所以一般也無須用 doNothing(), 況且 void 提供不了返回值作進一步 mock,只需要在事后用 verify() 進行驗證一下。

例如有下面的代碼

類 UserDao

 

 

類 UserService

 

 

要寫一個針對  UserService.saveUser(User user) 的測試方法

 

 

模擬 void 方法拋出異常時調用者的響應

這就是為什么 Google 上那么多答案告訴我們要用到 doThrow() 的原因,假如我們的 UserService.saveUser(User user) 方法在 userDao 報出 DataAccessException 時轉換為 ApplicationException 異常, 它的代碼實現如下:

 

 

要測試上面那個異常處理過程,我們可以寫下面的測試

 

 

 

上面的 doThrow() 行寫成下面的方式也是一樣的

doNothing().doThrow(new DataAccessException()).when(userDao).save(user);

Mockito 在調用 mock  對象的  void 方法時本來默認就是 doNothing. 那什么時候需要用到 doNothing() 呢?就是下面的情況

部分 mock 時 void 方法可 doNothing

除了 @Mock 或 Mockito.mock(Class<T>) 來創建 mock 對象,還可以使用 spy(realObject) 或 spy(Class) 來獲得 mock 對象,這兩種方式得到的 mock  對象是不同的。前者所有的方法都被 mock, 后者(spy) 未打樁的方法會調用被 spy 對象的實際實現。

看下面的例子如何對 spy 對象的方法進行 mock  的

 

 

上面的測試可成功通過,我們用 doNothing().when(spy).add(anyInt(), anyString()) 讓帶下標的方式添加元素什么也不做,而未被打樁的方法會調用 names 的實際實現。因此我們可以看到上面的斷言結果。

doNothing() 還真不是 doNothing(), 在搭配 spy 作部分 mock 時還是很有用的,如下面的測試

 

 

另外如果還有其他情況可考慮 doCallRealMethod() 或  doAnser()

doCallRealMethod().when(mockObject).voidMethod();
doAnswer(answer).when(mockObject).voidMethod();

相關鏈接:

  1. Mockito: How to mock a void method call
  2. How to make mock to void methods with mockito

 


注(2017-09-19):如果用 spy 進行部分 mock 的時候,和常規方法 mock 略有不同,比如要先申請 doReturn(...)

 

 

再次說明,spy 打樁的方法被 Mock, 未打樁的會調用實際方法。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM