在編寫程序的過程中,經常會用到靜態方法。靜態方法往往是一個固定的函數,可以直接通過類來調用,無需實例化對象。想要測試這類靜態方法,卻常常很難,因為不同的測試數據能夠引起不同的結果。為了解決這個問題,我們就需要使用Mock靜態方法來進行測試。下面,我們來詳細介紹Mock靜態方法的一些方面。
一、Mock靜態方法復原
在使用Mock靜態方法的時候,有時候我們需要復原某個靜態方法的方法體,讓它返回真實的結果。這時候我們可以使用PowerMockito.mockStatic方法,將靜態方法mock,然後使用PowerMockito.when()方法來指定其返回值。下面是使用PowerMockito.mockStatic方法的示例代碼:
public class StaticClass { public static int staticMethod() { return 1; } } @RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testStaticMethod() { PowerMockito.mockStatic(StaticClass.class); PowerMockito.when(StaticClass.staticMethod()).thenReturn(2); Assert.assertEquals(2, StaticClass.staticMethod()); } }
上述代碼中,我們使用了PowerMockito.mockStatic方法來mock了StaticClass類的靜態方法。然後我們使用PowerMockito.when()方法指定其返回值為2。最後我們判斷其返回值是否為2。因為復原了靜態方法的方法體,因此實際上返回的是真實的結果,並不是我們mock的結果。
二、Mock靜態方法無返回值
有時候,被測試的靜態方法並沒有返回值。這時候我們可以使用PowerMockito.doNothing()方法來指定其無返回值。下面是使用PowerMockito.doNothing()方法的示例代碼:
@RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testDoNothingStaticMethod() { PowerMockito.mockStatic(StaticClass.class); PowerMockito.doNothing().when(StaticClass.class); StaticClass.staticMethod(); StaticClass.staticMethod(); Assert.assertTrue(true); } }
上述代碼中,我們使用PowerMockito.doNothing()方法指定StaticClass類的靜態方法無返回值。然後我們連續調用了兩次靜態方法,最終判斷其返回值是否為true,來驗證其無異常。
三、Mock靜態方法不生效
有些時候,我們使用Mock靜態方法時會出現問題,導致mock並沒有生效。這時候,我們需要檢查一下是否有以下情況:
1、是否使用了PowerMockRunner類作為測試類的運行器;
2、是否使用了PrepareForTest註解,指定要mock的靜態方法所在的類;
3、是否添加了對應的Mock庫依賴;
4、是否在mock前調用了PowerMockito.mockStatic方法;
5、是否使用了正確的Mockito/PowerMockito的靜態方法。
同時,我們也可以打開PowerMock的調試日誌來幫助我們排除問題。下面是開啟調試日誌的代碼:
org.apache.log4j.BasicConfigurator.configure(); Logger.getRootLogger().setLevel(Level.DEBUG);
四、Mock靜態方法void
有些時候,我們需要mock帶有void返回值的靜態方法。在這種情況下,我們需要使用PowerMockito.doNothing()方法來mock,具體的方法如下示:
@RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testStaticMethodWithVoidReturnType() { PowerMockito.mockStatic(StaticClass.class); PowerMockito.doNothing().when(StaticClass.class); StaticClass.staticMethodWithVoidReturnType(); Assert.assertTrue(true); } }
五、Mock靜態方法並發
當一個方法被多次調用時,它可能會獲取它所需要的資源並改變其狀態,這可能會導致並發問題。在這種情況下,我們需要mock靜態方法來控制其並發行為。使用PowerMockito.doAnswer方法來模擬靜態方法的行為。
@RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testStaticMethodConcurrency() throws Exception { PowerMockito.mockStatic(StaticClass.class); PowerMockito.doAnswer(invocation -> { Thread.sleep(2000); return 1; }).when(StaticClass.class); StaticClass.staticMethod(); Assert.assertTrue(true); } }
六、靜態方法Mock測試
有時候我們需要測試一個類中的多個靜態方法。這時候我們可以使用Junit的Parameterized和Mockito的MockitoAnnotations來進行測試。下面是測試多個靜態方法的示例代碼:
@RunWith(Parameterized.class) public class StaticClassTest { @Mock private MockedStatic staticClassMock; @Parameterized.Parameters public static Collection
七、mockup靜態方法
在Java 9之前,我們可以使用MockUp類來mock靜態方法。下面是使用MockUp類來mock靜態方法的示例代碼:
@RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testStaticMethodWithMockUp() { new MockUp() { @Mock public int staticMethod() { return 2; } }; Assert.assertEquals(2, StaticClass.staticMethod()); } }
八、Mockito靜態方法
Mockito 3.4.0之後新增了Static方法的Mock,可以直接使用Mockito來Mock靜態方法。使用Mockito來Mock靜態方法只需要按照標準的Mockito的風格來實現即可。下面是使用Mockito來Mock靜態方法的示例代碼:
@RunWith(MockitoJUnitRunner.class) public class StaticClassTest { @Test public void testStaticMethod() { Mockito.mockStatic(StaticClass.class); Mockito.when(StaticClass.staticMethod()).thenReturn(2); Assert.assertEquals(2, StaticClass.staticMethod()); } }
九、Mock私有方法
Mock私有方法和Mock靜態方法的方式類似,只不過我們需要使用PowerMockito.spy方法來mock私有方法。下面是使用PowerMockito.spy來mock私有方法的示例代碼:
@RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class StaticClassTest { @Test public void testPrivateMethod() throws Exception { StaticClass sc = PowerMockito.spy(new StaticClass()); PowerMockito.doReturn(2).when(sc, "privateMethod"); Integer result = (Integer) Whitebox.invokeMethod(sc, "privateMethod"); Assert.assertEquals(2, result.intValue()); } }
十、Mock靜態對象選取
當進行靜態方法Mock測試時,我們有兩種選取靜態對象的方式,一種是Mock靜態方法所在的類,另一種是Mock靜態方法的調用出的對象。我們需要根據測試需要來選擇對應的方式。
@RunWith(MockitoJUnitRunner.class) public class StaticClassTest { @Test public void testStaticMethod() { Mockito.mockStatic(StaticClass.class); Mockito.when(StaticClass.staticMethod()).thenReturn(2); // 選取類的方式 Assert.assertEquals(2, StaticClass.staticMethod()); // 選取調用靜態方法的實例對象的方式 StaticClass sc = new StaticClass(); Assert.assertEquals(2, sc.staticMethod()); } }
本篇文章介紹了Mock靜態方法的幾個方面,包括如何復原靜態方法的方法體、Mock靜態方法無返回值、Mock靜態方法不生效、Mock靜態方法void、Mock靜態方法並發、靜態方法Mock測試、mockup靜態方法、Mockito靜態方法、Mock私有方法、Mock靜態對象選取等等。希望能夠對大家使用Mock靜態方法提供幫助。
原創文章,作者:FHXLK,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/369189.html