Problem
PowerMock最強大的地方,就是可以幫我們mock static method,還可以幫我們mock private method、constructor,甚至Java System classes。開發新功能無法避免使用到舊有的程式碼,而舊有的程式碼勢必有使用static method的utility class。本篇文章將分享如何撰寫測試,讓你可以正常的看到SUT(software under test)程式碼的coverage。
How to?
以下是本篇文章範例的類別圖:
SUT提供testMethod功能,會使用DOC(Depended-on Component)所提供的static method delegatedMethod。接下來我將使用PowerMockito去mock DOC static的行為:@RunWith(PowerMockRunner.class) @PrepareForTest({DOC.class}) public class SUTTest { @Test public void shouldReturnMockData_WhenDelegateExecutionToStaticMockDOC() { // Given String expectData = "MockData"; mockStatic(DOC.class); doReturn(expectData).when(DOC.class); DOC.delegatedMethod(); // When SUT sut = new SUT(); String realData = sut.testMethod(); // Then assertEquals(expectData, realData); } }
接下來我們使用JUnit+code coverage tool去跑測試,以下為執行結果:
由此可見,mock “一般”的static method並不會造成coverage問題。但為什麼會有人對coverage問題抱持疑問呢? 答案是因為誤把SUT加到了@PrepareForTest之中:
由此可見,mock “一般”的static method並不會造成coverage問題。但為什麼會有人對coverage問題抱持疑問呢? 答案是因為誤把SUT加到了@PrepareForTest之中:
@RunWith(PowerMockRunner.class) @PrepareForTest({SUT.class, DOC.class}) public class SUTTest { ...
什麼時候會需要將SUT加入@PrepareForTest之中呢? 答案是如果你要Mock SUT裡面行為或者是Java System classes(如java.lang.*的class)的行為。
- Mock SUT裡面的行為代表你的SUT沒設計好,請重新想想你的設計。
- 面對Mock Java System classes的情況,如果你想要能夠正常看到coverage,不妨使用wrapper class去包裝使用到的物件。根據這篇文章,目前沒有一個很容易讓你使用powermock又可以正常使用coverage tool的方法,至少我還沒成功過。
留言
張貼留言