Problem
我想測試getWindowsMajorVersion method,但由於使用了static block導致我無法同時測到在Windows與Linux的情況:
public class PlatformUtil { private final static String mOSName = System.getProperty("os.name"); private final static boolean IS_WINDOWS; static { IS_WINDOWS = mOSName.toUpperCase().indexOf("WINDOWS") != -1; } public static boolean isWindows(){ return IS_WINDOWS; } public static int getWindowsMajorVersion(){ if( !isWindows() ){ return -1; } String osVersion = System.getProperty("os.version"); int dotIndex = osVersion.indexOf("."); String majorVersionStr = osVersion; if( dotIndex != -1 ){ majorVersionStr = osVersion.substring(0, dotIndex); } try { return Integer.valueOf(majorVersionStr); } catch( NumberFormatException e ){ return -1; } } }
Solution
Suppress static initializer
Powermock提供@SuppressStaticInitializationFor的annotation讓你可以skip static init。加上這個annotation,接著在testcase中去mockStaticPartial isWindows method,就可以完成在Windows與Linux上的測試案例:
@RunWith(PowerMockRunner.class) @PrepareForTest({PlatformUtil.class, System.class}) @SuppressStaticInitializationFor("org.tonylin.practice.powermock.PlatformUtil") public class TestPlatformUtil private void mockIsWindowsResult(boolean aResult){ PowerMock.reset(PlatformUtil.class); PowerMock.mockStaticPartial(PlatformUtil.class, "isWindows"); PlatformUtil.isWindows(); PowerMock.expectLastCall().andReturn(aResult).anyTimes(); PowerMock.replay(PlatformUtil.class); } @Test public void getWindowsMajorVersion(){ PowerMock.mockStatic(System.class); // mock the os is windows. mockIsWindowsResult(true); mockWindowsProperties("Windows XP", "5.1.2600"); assertEquals( 5, PlatformUtil.getWindowsMajorVersion()); mockWindowsProperties("Windows 7", ""); assertEquals( -1, PlatformUtil.getWindowsMajorVersion()); mockWindowsProperties("Windows 7", "ss"); assertEquals( -1, PlatformUtil.getWindowsMajorVersion()); // mock the os is linux. mockIsWindowsResult(false); mockWindowsProperties("Linux", "6.1"); assertEquals( -1, PlatformUtil.getWindowsMajorVersion()); } }
留言
張貼留言