6.1 模擬靜態方法 mockStatic()
還有更重要的一點是靜態方法的模擬和驗證。“那有什麼問題嗎?”你問。是的,靜態的,但是方法是一樣的。你會錯的。
還記得我們是從哪裡開始學習模擬對象的嗎?由於這些對像是通過DynamicProxy
. 並且靜態方法不綁定任何對象,DynamicProxy
不可能通過.攔截對它們的調用。就這樣。
但是 Mockito 的創建者也能夠在這裡躲避 - 他們編寫了自己的類加載器,並且在它的幫助下他們能夠動態替換類。一項艱鉅的工作,但他們仍然設法做到了。
您將需要添加一個額外的庫到pom.xml
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.2.0</version>
<scope>test</scope>
</dependency>
如果你需要模擬一個靜態方法,下面是如何工作的。
1 創建一個特殊的模擬類對象:
MockedStatic<ClassName>managerObject = Mockito.mockStatic(ClassName.class);
2 給這個對象添加操作規則:
為了規則的這個目標,有必要以其他方式堅持。
managerObject.when(ClassName::method name).thenReturn(result);
3一定要將這個對象的使用包裹進去,try-with-resources
這樣這個對象會立即被刪除,Mockito 可以清除與之關聯的規則。
例子:
@Test
void givenStaticMethodWithNoArgs () {
try (MockedStatic< StaticUtils> utilities = Mockito.mockStatic( StaticUtils.class)) {
// add rule
utilities.when(StaticUtils::name).thenReturn("Hello");
// check if the rule works
assertEquals("Hello", StaticUtils.name());
}
}
沒有註解@Mock
和那麼漂亮@Spy
,但非常實用。當無法模擬在被測方法內部使用的簡單靜態方法時,編寫測試非常困難。