Mock partial static method with PowerMockito

我們可以透過PowerMock的mockStaticPartial去mock部分的static method:

		PowerMock.mockStaticPartial(System.class, "getProperty");
 
		System.getProperty("test");
		PowerMock.expectLastCall().andReturn("test").anyTimes();
 
		PowerMock.replayAll();
 
		System.out.println(System.getProperty("test"));
 
		PowerMock.verifyAll();
如果想用PowerMockito該如何做呢? 我們可以使用spy:

		PowerMockito.spy(System.class);
		PowerMockito.doReturn("test").when( System.class, "getProperty", "test");
 
		// 如果是沒任何回傳值的method,可以使用PowerMockito.doNothing()
 
		System.out.println(System.getProperty("test"));
這種寫法存在的問題有兩個,

  1. 如果要呼叫的method有overloading,且使用Matchers.any當參數,將導致NullPointerException。問題發生原因為PowerMock會將Matchers.any產生的類別型態,識別為null,在判斷呼叫參數時就發生問題。
  2. 如果method名稱有修改,將不容易查覺。

因此第二種寫法如下:

		PowerMockito.spy(System.class);
		PowerMockito.doReturn("test").when( System.class);
		System.getProperty("test");
 
		System.out.println(System.getProperty("test"));
 
		PowerMock.verifyAll();
第二種方法的缺點是無法mock private method。第三種做法是透過WhiteboxImpl去取得method instance,再透過when去呼叫,可以參考此link

這三種做法,我還沒找到一個較好final solution。不管用哪一種,都可能會有side-effect。如第三種做法去mock System.getProperty就發生與link相同問題。


友藏內心獨白: 實際應用會遇到更多問題的!