Mock 普通方法
假設要Mock \(Properties.class\) 中的 \(getProperty\) 方法
思路是先Mock一個對象,然後再修改該對象中的某個方法,然後再通過反射將原\(Properties\)對象替換爲Mock的對象。
Properties configProperties = PowerMockito.mock(Properties.class);
PowerMockito.when(configProperties.getProperty("platform")).thenReturn("cm");
Field field = MongoConfigService.class.getDeclaredField("configProperties");
field.setAccessible(true);
field.set(mongoConfigService, configProperties);
Mock static method
能夠Mock靜態方法,是PowerMock相對於mockito 的優勢,PowerMock有自己寫的runner,Mock靜態方法時,通過使用PowerMockRunner進行運行可以修改靜態方法。
假設我們要Mock \(InitAllService\) 類中的靜態方法
首先要在測試類前加上:
@RunWith(PowerMockRunner.class) //代表該測試類用PowerMockRunner啓動
@PrepareForTest({InitAllService.class}) //需要Mock的類名
在Mock時,需要先mockStatic再次指定Mock類名,然後spy方法類似於Mock,但又有許多不同,在後面會介紹這兩者的區別。
doAnswer...when是修改 \(InitAllService.getService\) 方法
PowerMockito.mockStatic(InitAllService.class);
PowerMockito.spy(InitAllService.class);
PowerMockito.doAnswer(invocation -> {
Object[] args = invocation.getArguments();
return new FakeIndividualServiceImpl();
}).when(InitAllService.class, "getService", IndividualServiceImpl.class);
細節
spy和mock的區別
mock方法和spy方法都可以對對象進行mock。但是前者是接管了對象的全部方法,而後者只是將有樁實現(stubbing)的調用進行mock,其餘方法仍然是實際調用。
意思是mock是產生一個新對象,該對象不含有原對象所含有的代碼,只含有mock的方法
而spy產生的對象則含有原對象的所有方法,但mock的方法會被優先調用。
使用 \(when...thenCallRealMethod\) 可以訪問到原對象的方法。
doAnswer...when 和 when...thenAnswer的區別
\(when...thenAnswer...\)做了真實調用。只是返回了指定的結果
\(doAnswer... when...\)不做真實調用