在使用Mockito進行單元測試時遇到的問題

之前的項目中,後端項目的單元測試都是構造出相應的數據而後存入數據庫中,這種方式,在功能簡單時還好,當功能趨於複雜時,就須要花費大量的時間去構造實驗數據,前段時間,潘老師找到了一種新的單元測試方式——使用Mockito 。前兩天做出了第一次嘗試,期間遇到了一些問題,在詢問潘老師後獲得瞭解決,在此記錄一番。html

如何使用

使用方法能夠看這篇文章git

Invalid use of argument matchers!

開始時使用的github

Mockito.when(scoreServiceSpy.  
       getAllFailScoreByPage(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Pageable.class))).thenReturn(mockScorePage);

使用的時候,會出現以下錯誤。
image.png
解決辦法在錯誤中也已經給出,當使用matchers,全部的參數都須要提供爲matcher
image.png
可是我上面的方法中確實全部的都是用的matcher呀,繼續看潘老師的教程,
image.png
嘗試切換成spring

doReturn().when()

不過在這裏又犯了一個粗心的錯誤……數據庫

// 我寫的代碼
Mockito.doReturn(mockScorePage).when(scoreServiceSpy) 
        .getAllFailScoreByPage(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Pageable.class)));

// 正確的代碼  
Mockito.doReturn(mockScorePage).when(scoreServiceSpy)  
        .getAllFailScoreByPage(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.anyLong(), Mockito.any(Pageable.class));

括號的位置錯了!後端

開始時,發現這個也錯,覺得問題不在這,而是寫法有問題,翻來覆去找都沒找到問題,只能求助於潘老師了。springboot

通過潘老師的講解,總算明白了。ide

首先,咱們須要明白兩種寫法的區別單元測試

doReturn().when()與when().thenReturn()

潘老師在教程中已經提供了延伸閱讀,只是當時還沒來得及看。測試

官方的說法

doReturn().when()是無反作用的。
when().thenReturn()是有反作用的

上述說法能夠這麼理解:

使用Mockito.when(scoreServiceSpy.getAllFailScoreByPage(xxx)),
scoreServiceSpy.getAllFailScoreByPage(xxx)這個方法就會真正的被執行。
而使用Mockito.doReturn(mockScorePage).when(scoreServiceSpy).getAllFailScoreByPage(xxxx)時,後面的方法並不會執行。

到這也大概明白了上面出現問題的緣由。
進入getAllFails()裏面。
image.png
能夠看到findAll()有兩個參數,其中pageable是經過matcher生成的,specification不是。

Unfinished stubbing detected here:

問題尚未徹底解決。
image.png

出現這個的緣由,潘老師猜想是由於第三條,由於在單元測試中使用了@MockBean,經過這個注入的對象有幾個特色:

  • 是全局的
  • 該對象有原對象的全部方法,但方法沒有功能。
  • 調用有返回值的方法時,若沒有經過Mockito設置返回值,就會出現上述錯誤。

因此,出現上述錯誤的緣由多是
image.png

相關文章
相關標籤/搜索