怎樣使用PowerMockito 測試靜態方法

PowerMockito 測試靜態方法

假如有下面一個類DemoStatic,它裡面定義瞭各種靜態方法,這些靜態方法可能是一些Utilities方法,輔助其它的類。

package mock.demo;
public class DemoStatic {
 public static String sayHello() {
  return "Hello";
 }
 
 public static String saySomething(String word) {
  return word;
 } 
 
 public static void sayAgain() {
  System.out.println(getMyWord());
 } 
 
 private static String getMyWord() {
  return "This is my word";
 }
}

首先

我們寫一個測試類DemoStaticTest.java, 如下:

@RunWith(PowerMockRunner.class)
@PrepareForTest({DemoStatic.class})
public class DemoStaticTest {
}

註意在類的前面要加這個annotation:

@PrepareForTest({DemoStatic.class})

其次

需要在你的項目中加入下面的maven依賴:

  <dependency>
   <groupId>org.powermock</groupId>
   <artifactId>powermock-api-mockito</artifactId>
   <version>1.4.10</version>
  </dependency>
  <dependency>
   <groupId>org.powermock</groupId>
   <artifactId>powermock-module-junit4</artifactId>
   <version>1.4.10</version>
  </dependency>

Mock 無參數的靜態方法

 @Test
 public void testMockSayHello() {
  PowerMockito.spy(DemoStatic.class);
  PowerMockito.when(DemoStatic.sayHello()).thenReturn("my hello");
  
  System.out.println(DemoStatic.sayHello());  // my hello
 }

Mock 帶參數的靜態方法

 @Test
 public void testSaySomething() throws Exception {
  PowerMockito.spy(DemoStatic.class);
  PowerMockito.when(DemoStatic.class, "saySomething", Mockito.anyString()).thenReturn("something to say!");
  
  System.out.println(DemoStatic.saySomething("say hello")); //something to say!
 }

Mock private 靜態方法

 @Test
 public void testMockPrivate() throws Exception {
  PowerMockito.spy(DemoStatic.class);
  PowerMockito.when(DemoStatic.class, "getMyWord").thenReturn("Nothing to say");
  
  DemoStatic.sayAgain(); //Nothing to say
 }

PowerMock 靜態方法模擬問題排查,結果是函數參數問題

問題:靜態方法User.convert()的模擬,未匹配到預期值。

1. 檢查靜態方法的模擬過程

Mocking Static Method:
// 1.類註解:@PrepareForTest(Static.class) //Static.class 是包含 static methods的類
方法內:
// 2.模擬靜態類(使用PowerMockito.spy(class)模擬特定方法)
PowerMockito.mockStatic(Static.class);
// 3.攔截:設置期望值
Mockito.when(Static.firstStaticMethod(param)).thenReturn(value);

檢查過程沒問題。 直接攔截靜態方法試試

2. 直接攔截靜態方法

驗證通過,模擬靜態方法沒問題。

3. 初步定義為參數問題:函數式參數

// 攔截的方法
<E, R> List<R> queryForList(Object var1, Class<E> var2, Function<E, R> var3);

Function類型的參數精確配置不應該 User::convert 這樣傳。那該怎麼傳呢?我在官網和百度扒資料,然而不知道是沒有,還是沒找對。反正,沒找到該怎麼解決。

沒辦法,隻好先模糊匹配下瞭

4. 隻匹配類型,算解決問題嗎

花瞭時間不一定有收獲,不花時間也許也有收獲呢。

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: