2013-03-01 91 views
6

我是Mockito和PowerMockito的新手。我發現我不能用純Mockito測試靜態方法,所以我需要用戶PowerMockito(對吧?)。爲什麼我應該嘲笑?

我有一個名爲驗證與此非常簡單的方法

public class Validate { 
     public final static void stateNotNull(
      final Object object, 
      final String message) { 
    if (message == null) { 
     throw new IllegalArgumentException("Exception message is a null object!"); 
    } 
    if (object == null) { 
     throw new IllegalStateException(message); 
    } 
} 

所以我需要驗證非常簡單的類:

1)當我打電話,關於空消息的說法靜態方法,IllegalArgumentException的叫
2)當我打電話,關於空對象參數靜態方法,IllegalStateException異常被稱爲

從我走到這一步,我寫了這個測試:

import static org.mockito.Matchers.anyString; 
import static org.mockito.Matchers.isNull; 

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

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Validate.class) 
public class ValidateTestCase { 

    @Test(expectedExceptions = { IllegalStateException.class }) 
    public void stateNotNullTest() throws Exception { 
     PowerMockito.mockStatic(Validate.class); 
     Validate mock = PowerMockito.mock(Validate.class); 
     PowerMockito.doThrow(new IllegalStateException()) 
      .when(mock) 
      .stateNotNull(isNull(), anyString()); 
     Validate.stateNotNull(null, null); 
    } 
} 

所以這個說,我嘲笑Validate類和我檢查,當模擬被稱爲與null參數爲對象,以及任何字符串作爲消息的方法,則拋出IllegalStateException。

現在,我真的不明白。爲什麼我不能直接調用這個方法,放棄整個巫術魔法來嘲弄那個靜態類?在我看來,除非我調用Validate.stateNotNull測試通過...爲什麼我應該嘲笑它?

回答

8

首先,確定你的目標是什麼以及你想測試什麼。您的測試不會測試您的Validate類方法,它會創建一個類似於該方法的模擬,如Fortega points out。確定你正在測試的東西(被測對象)以及你需要什麼來執行測試(協作者),然後看看協作者,並確定他們是否易於創建或者你需要的東西嘲笑他們。

對於像這個類沒有任何依賴關係的東西,我會建議完全沒有嘲笑。這裏沒有什麼需要嘲諷,測試可以這樣寫:

import static org.junit.Assert.*; 

public class ValidateTestCase { 

    @Test 
    public void testHappyPath() throws Exception { 
     Validate.stateNotNull("", ""); 
    } 

    @Test 
    public void testNullMessage() throws Exception { 
     try { 
      Validate.stateNotNull(null, null); 
      fail(); 
     } 
     catch (IllegalStateException e) { 
      String expected = "Exception message is a null object!" 
      assertEquals(expected, e.getMessage()); 
     } 
    } 

    @Test(expected=IllegalStateException.class) 
    public void testNullObject() throws Exception { 
     Validate.stateNotNull(null, "test"); 
    } 
} 

,並告訴你的代碼是否做了你希望它是什麼。

不要模擬,除非有一些你想避免引入到測試中的依賴項,因爲它是外部資源(如文件系統或數據庫)或一些複雜的子系統。模擬框架可能非常有用,但它們增加了複雜性,它們可以過度指定它們正在測試的事物的行爲,使得測試變得脆弱,並且它們可以使測試難以閱讀。如果可以的話,請儘量不要。

11

你不應該嘲笑你正在測試的類和方法。您應該只模擬執行測試本身所需的方法。

例如,如果您需要Web服務中的某些對象執行測試,則可以模擬Web服務調用,因此您不需要實際調用Web服務。