2016-11-10 114 views
0

我想用一堆靜態方法來測試一個實用工具類。我正在爲一個調用另外兩個靜態方法的方法編寫測試。在第一個靜態方法調用模擬似乎工作,但它忽略了第二個期望,並調用真正的方法。任何想法?我在第二次期望之前嘗試提供第二個PowerMock.spy(Utils.class),但沒有運氣。任何想法如何解決這個問題?PowerMockito和靜態方法

這裏是示例代碼。

package com.personal.test; 

import java.io.IOException; 

public class Utils { 

    public static String testUtilOne() { 
     System.out.println("Static method one"); 
     return "methodone"; 
    } 

    public static void testUtilsTwo(String s1, String s2, String s3) throws IOException { 
     throw new IOException("Throw an exception"); 
    } 

    public static void testUtilsThree() throws TestException { 
     try { 
      String s = testUtilOne(); 
      testUtilsTwo("s1", s, "s3"); 
     } catch (IOException ex) { 
      throw new TestException("there was an exception", ex); 
     } 
    } 

    public static class TestException extends Exception { 
     public TestException() { 
      super(); 
     } 
     public TestException(String message, Exception cause) { 
      super(message, cause); 
     } 
    } 
} 


    package com.personal.test; 

import java.io.IOException; 

import org.junit.Assert; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mockito; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

import com.personal.test.Utils.TestException; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Utils.class}) 
public class UtilsTest { 

    @Test 
    public void testMethodThreeWrapsException() throws Exception { 
     PowerMockito.spy(Utils.class); 
     PowerMockito.when(Utils.class, "testUtilOne").thenReturn("This is coming from test"); 
     PowerMockito.spy(Utils.class); 
     PowerMockito.when(Utils.class, "testUtilsTwo", Mockito.anyString(), Mockito.anyString(), Mockito.anyString()).thenThrow(new IOException("Exception from test")); 
     try { 
      Utils.testUtilsThree(); 
     } catch (TestException ex) { 
      Assert.assertTrue(ex.getCause() instanceof IOException); 
      Assert.assertEquals("Exception from test", ex.getMessage()); 
     } 
    } 
} 
+0

只是爲了記錄:如果必須的話,只能使用* Power *框架進行靜態模擬。大多數時候當人們要求Powermock時......那是因爲他們創造了難以/不可測試的代碼;他們認爲使用Powermock會解決這個問題。不,它不會。真正的答案是應用良好的面向對象技術,並不使用Powermock; - 。) – GhostCat

回答

1

只是在情況下,如果任何人有興趣,花一整天時間,我終於解決這個問題了之後。我首先staticMocked我的Utils類(這將模擬所有的靜態方法)比問模擬調用testUtilsThree調用真正的方法。 更改如下。

 package com.personal.test; 

import java.io.IOException; 

import org.junit.Assert; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mockito; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

import com.personal.test.Utils.TestException; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest({Utils.class}) 
public class UtilsTest { 

    @Test 
    public void testMethodThreeWrapsException() throws Exception { 
     PowerMockito.mockStatic(Utils.class); 
     PowerMockito.when(Utils.class, "testUtilOne").thenReturn("This is coming from test"); 
     PowerMockito.when(Utils.class, "testUtilsTwo", Mockito.anyString(), Mockito.anyString(), Mockito.anyString()).thenThrow(new IOException("Exception from test")); 
     PowerMockito.doCallRealMethod().when(Utils.class, "testUtilsThree"); 
     try { 
      Utils.testUtilsThree(); 
     } catch (TestException ex) { 
      Assert.assertTrue(ex.getCause() instanceof IOException); 
      Assert.assertEquals("Exception from test", ex.getMessage()); 
     } 
    } 
} 
+0

我想建議使用[ExpectedException](http://junit.org/junit4/javadoc/4.12/org/junit/rules/ ExpectedException.html),而不是嘗試catch塊來聲明異常。 –

+0

感謝亞瑟,我用try catch,因爲下游代碼拋出三個不同的異常,這些異常被封裝到我的示例代碼不顯示的自定義異常中。所以根據什麼是GIVEN下游代碼會拋出不同的異常。 – ringadingding

相關問題