Problem
我們可以透過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:
How to?
PowerMockito.spy(System.class); PowerMockito.doReturn("test").when( System.class, "getProperty", "test"); // 如果是沒任何回傳值的method,可以使用PowerMockito.doNothing() System.out.println(System.getProperty("test"));
這種寫法存在的問題有兩個,
- 如果要呼叫的method有overloading,且使用Matchers.any當參數,將導致NullPointerException。問題發生原因為PowerMock會將Matchers.any產生的類別型態,識別為null,在判斷呼叫參數時就發生問題。
- 如果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相同問題。
友藏內心獨白: 實際應用會遇到更多問題的!
留言
張貼留言