2016-05-13 83 views
4

我想驗證表明public static void方法已被稱爲驗證呼叫靜態方法

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ConsoleLog.class}) 
public class AdContentDataUnitTest { 

    @Before 
    public void setUp() throws Exception { 
     PowerMockito.mockStatic(ConsoleLog.class); 
    } 

    @Test 
    public void adContentData_sendTrackingEvent_noUrl() throws Exception { 
     mAdContentData = spy(mAdContentData); 

     // PowerMockito.doNothing().when(ConsoleLog.class); 

     verifyStatic(); 
     mAdContentData.sendTrackingEvent("event1"); 
     //verifyStatic(); 
    } 
} 

sendTrackingEvent將被調用,並ConsoleLog.v(String, String)將被調用。我可以在調試,靜態方法被調用時看到,但下面的日誌出現,測試失敗:

Wanted but not invoked com.example.logger.ConsoleLog.v(
    "AdContentData", 
    "sendTrackingEvent: event event1 does not exist." 
); 

我做過嘗試,但相同的日誌後添加verifyStatic,如果我刪除第一個驗證,沒有被檢查。如果我嘲笑整個ConsoleLog類,則出現錯誤Unfinished stubbing detected here: [...] PowerMockitoCore.doAnswer

有誰知道如何正確地做到這一點?

回答

1

有誰知道如何正確地做到這一點?

是的。不要這樣做。

比方說,你有一個調用靜態方法是這樣一類:

class Person { 
    private final int id; 

    Person() { 
     id = IdGenerator.gen(); 
    } 
} 

提取靜態調用非靜態方法:

class Person { 
    private final int id; 

    Person() { 
     id = generateId(); 
    } 

    protected int generateId() { 
     return IdGenerator.gen(); 
    } 
} 

現在你可以寫一個測試,覆蓋提取的方法:

final int id = 1; 
    Person person = new Person() { 
     @Override 
     protected int generateId() { 
      return id; 
     } 
    }; 

    // test with person, knowing we control id 

但理想的解決方案實際上是將被測代碼重構爲n根本不使用這種靜態調用,而是依賴注入。

+0

這是一個解決方案,但它降低了性能,因爲我們需要更多地調用一個方法(我在Android和性能方面) –

+0

編譯器可能很好地內聯這樣的方法調用。你確定它有明顯的性能差異嗎?你測過它了嗎?我忘了提到理想的解決方案是重構代碼在測試中不使用靜態調用,但使用依賴注入 – janos

+0

好吧,'ConsoleLog'是一個包裝類的http://developer.android.com/reference/android/util /Log.html –