使用powerMock和mockito模拟静态方法和私有方法

时间:2021-06-15 19:30:18

首先我们要导入相应的包

<dependency>  
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.4.12</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.5</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.4.12</version>
<scope>test</scope>
</dependency>

被测试类

    public static boolean webchatEnable(String language){
....
}

public static String getWebChatPages(String language){
....
}

private static boolean webchatInHours(){
....
}

private static boolean webchatLanguageEnable(String language){
...
}

private static Calendar getCurrentTime(){
return Calendar.getInstance();
}


测试类

    @RunWith(PowerMockRunner.class)  //1
@PrepareForTest({PropertyApplicationContext.class,WebChatUtil.class}) //2
public class WebChatUtilTestCase extends AbstractJUnit {

@Before
public void init(){
PowerMockito.mockStatic(PropertyApplicationContext.class);// 3
PowerMockito.mockStatic(WebChatUtil.class);
}

@Test
public void testWebchatEnable(){
try {
Calendar c = Calendar.getInstance();
c.set(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE), 16, 35);
PowerMockito.spy(WebChatUtil.class); // 创建spy,如果不创建的话,后面调用WebChatUtil就都是Mock类,这里创建了spy后,只有设置了mock的方法才会调用mock行为
PowerMockito.doReturn(c).when(WebChatUtil.class, "getCurrentTime"); //Mock私有方法
} catch (Exception e) {
e.printStackTrace();
}
PowerMockito.when(PropertyApplicationContext.getProperty(PropertyConstants.WEBCHAT_HOURS)).thenReturn("0900,1800"); //4 - Mock静态方法,返回期望值
PowerMockito.when(PropertyApplicationContext.getProperty(PropertyConstants.WEBCHAT_LOCALES)).thenReturn("en,sc,cn");

Assert.assertTrue(WebChatUtil.webchatEnable("en"));

PowerMockito.when(PropertyApplicationContext.getProperty(PropertyConstants.WEBCHAT_HOURS)).thenReturn("090,1800");
PowerMockito.when(PropertyApplicationContext.getProperty(PropertyConstants.WEBCHAT_LOCALES)).thenReturn("en,sc,cn");
Assert.assertFalse(WebChatUtil.webchatEnable("en"));

PowerMockito.when(PropertyApplicationContext.getProperty(PropertyConstants.WEBCHAT_HOURS)).thenReturn("0900,1800");
PowerMockito.when(PropertyApplicationContext.getProperty(PropertyConstants.WEBCHAT_LOCALES)).thenReturn("en,sc,cn");
Assert.assertFalse(WebChatUtil.webchatEnable("th"));
}

        ① 标注使用PowerRunner运行test(powermock会修改字节码)

② 设置mock类(支持多个类,逗号分隔),这个可以设置到class上,也可以设置到method上。这里面包含两种类型: 

            被mock的类(如上例MyStringUtil .class,如果mock类为系统类,如System.class,则不需要这里设置就可以使用)

            context类,如果是在XxxServer里面希望mock MyStringUtil类,则要设置 XxxServer.class

③ 告诉powermock需要mock哪个类。(感觉这里配置和②有点重合)

④ 打桩,设置mock对象返回预期值。(测试mock方法还未执行)