1. 程式人生 > >使用powerMock和mockito模擬靜態方法和私有方法

使用powerMock和mockito模擬靜態方法和私有方法

首先我們要匯入相應的包

<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方法還未執行)