說下背景,java單元測試想要進行mock,於是查到了這個框架,就應用了一下,遇到了一些問題記錄一下。
1、想要測試Service層的類,但是Service層引用了dao層的Mapper,需要mapper進行注入,也就是說Mock一個假的mapper
拋出一個異常如下:
org.mockito.exceptions.base.MockitoException: Mockito cannot mock this class: interface com.hikvision.hikkan.contentmgr.console.mapper.ConsoleNewsMapper. Mockito can only mock non-private & non-final classes. If you're not sure why you're getting this error, please report to the mailing list.
看原因是mock失敗,搜了挺多百思不得其解?最后蛛絲馬跡中,可能和jdk版本有關,切換為 1.8 錯誤消失。
以上問題,可以在pom中手動引入mockito框架,java11對應 2.22.0版本的mockito 是正常的。
2、使用屬性注入
代碼中,都是通過@Autowire進行屬性注入的,https://www.tutorialspoint.com/mockito/mockito_create_mock.htm 文檔中使用的是構造器注入的,可以這么寫完成屬性注入。
@InjectMocks 必須放在實現類上,interface上不行,我最開始用的是服務的接口,報錯了
@Mock 注解說明是一個可以被注入的服務。
3、設置Mock的時候,期望返回,拋出異常,
org.mockito.exceptions.misusing.WrongTypeOfReturnValue: ConsoleNewsEntity cannot be returned by toString() toString() should return String *** If you're unsure why you're getting above error read on. Due to the nature of the syntax above problem might occur because: 1. This exception *might* occur in wrongly written multi-threaded tests. Please refer to Mockito FAQ on limitations of concurrency testing. 2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies - - with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
想從thenReturn 返回上面 PrimaryId 對應的是Entity實例,dbList是我預設的列表。
改成這樣可以
4、mock獲取方法參數的方式
如下圖所示
獲取update方法對應的輸入參數。
5、Mockito如何對參數為null的方法進行匹配呢?
有一種情況,mock的方法,可能會失效。當參數類表中使用了Interger這樣的包裝類,但是傳入的確是null的時候。
像我這樣寫,編譯的時候不會報錯,但是傳入null作為參數的時候,此刻 userRecordService.searchHistoryInfo 就會返回null 。並非我們自己的設置的值。
要想讓他匹配到null值可以做如下處理。使用 Mockito.IsNull() 替換