Problem
在Mock System.exit中,我們有遇到exception path該如何測的問題。第一個方法是將new Example抽出為static的createExample,再用powermock去mock它 (記得在efficiency java中看過,它建議你將new Example寫成createExample的method去產生instance);第二個方法是直接使用powermock的mock construcor功能。無論如何,在mock出example instance後,都需要再mock doSomething讓它拋出exception。在這我使用第二個方法為大家做說明。
package org.tonylin.powermock; public class Example { public Example(){ } public void doSomething(){ } public static void main(String[] args) { try { new Example().doSomething(); } catch( Exception e ){ System.exit(1); } finally { System.exit(0); } } }
How to solve?
首先我們需mock System.exit為1的情況,接著透過PowerMock.createMockAndExpectNew(Example.class)讓new Example都會產生這個mock object。在example.doSomething()後,透過PowerMock.expectLastCall().andStubThrow去拋出RuntimeException,這能夠讓main程式出現exception情況。最後reply再執行。
@RunWith(PowerMockRunner.class) @PrepareForTest({Example.class}) public class TestExample { @Test public void testMainWithException() throws Exception{ // mock System.exit PowerMock.mockStatic(System.class); System.exit(1); PowerMock.expectLastCall().times(1); // mock constructor Example example = PowerMock.createMockAndExpectNew(Example.class); example.doSomething(); PowerMock.expectLastCall().andStubThrow(new RuntimeException()); PowerMock.replayAll(); Example.main(new String[0]); } }
如果你使用的情況是Class A去new Class B,而你要mock Class B,要記得把Class A加到PrepareForTest中喔!
PowerMock.createMockAndExpectNew(Example.class)的寫法,也可改為這種寫法:
Example example = PowerMock.createNiceMock(Example.class); PowerMock.expectNew(Example.class).andReturn(example);
但我想沒人會想做多寫一行的事情吧? (MJ是你嗎?)
留言
張貼留言