2014-10-02 154 views
12

我用mock編寫單元測試時遇到了問題。有一個我需要模擬的對象有很多getter,我在代碼中調用它們。但是,這些不是我的單元測試的目的。那麼,有沒有辦法嘲笑所有的方法,而不是一個一個地模擬它們。Mockito模擬所有方法調用並返回

下面是代碼例如:

public class ObjectNeedToMock{ 

private String field1; 
... 
private String field20; 

private int theImportantInt; 


public String getField1(){return this.field1;} 
... 

public String getField20(){return this.field20;} 

public int getTheImportantInt(){return this.theImportantInt;} 

} 

,這是服務類我需要測試類內檢驗

public class Service{ 

public void methodNeedToTest(ObjectNeedToMock objectNeedToMock){ 
    String stringThatIdontCare1 = objectNeedToMock.getField1(); 
    ... 
    String stringThatIdontCare20 = objectNeedToMock.getField20(); 
    // do something with the field1 to field20 

    int veryImportantInt = objectNeedToMock.getTheImportantInt(); 
    // do something with the veryImportantInt 

    } 
} 

,測試方法是像

@Test 
public void testMethodNeedToTest() throws Exception { 
     ObjectNeedToMock o = mock(ObjectNeedToMock.class); 
     when(o.getField1()).thenReturn(anyString()); 
     .... 
     when(o.getField20()).thenReturn(anyString()); 

     when(o.getTheImportantInt()).thenReturn("1"); //This "1" is the only thing I care 

} 

那麼,有沒有辦法可以避免將無用的「field1」寫入「field20」的所有「when」

+0

您不必如果你罰款他們返回空。 – 2014-10-02 05:21:12

+0

我確實需要在方法中使用它們,對不起,請不要在示例中使用它們。 – jasonfungsing 2014-10-02 05:23:22

回答

22

您可以控制模擬的默認答案。當你創建模擬,使用方法:

Mockito.mock(ObjectNeedToMock.class, new Answer() { 
    @Override 
    public Object answer(InvocationOnMock invocation) throws Throwable { 
     /* 
      Put your default answer logic here. 
      It should be based on type of arguments you consume and the type of arguments you return. 
      i.e. 
     */ 
     if (String.class.equals(invocation.getMethod().getReturnType())) { 
      return "This is my default answer for all methods that returns string"; 
     } else { 
      return RETURNS_DEFAULTS.answer(invocation); 
     } 
    } 
})); 
+0

不知道我是否正確理解你的答案。我仍然需要在答案方法中將field1的默認值手動設置爲field20? – jasonfungsing 2014-10-02 05:27:13

+2

@jasonfungsing不,你不知道。在這種情況下,您正在設置模擬對象的默認行爲。事實上,如果你調用'doReturn(...)。when()'你會用新的自定義存根覆蓋這個默認行爲。因此,如果您需要更改某個方法的行爲,而其他方法仍然會返回默認值,這將非常有用。順便說一句,我已經更新了我的答案。 – SimY4 2014-10-02 05:33:31

+0

你也可以做 'mock(ObjectNeedToMock.class,RETURNS_DEFAULTS);' 不需要lambda。 – Amalgovinus 2017-07-26 18:43:47

0

如果你不感興趣的特定測試用例getField1()getField20()的結果,你不應該嘲笑它。換句話說,如果所有具體的測試用例應該關注的是getTheImportantInt(),那麼你的測試用例應該是這樣的:

@Test 
public void testMethodNeedToTest() throws Exception { 
     ObjectNeedToMock o = mock(ObjectNeedToMock.class); 
     when(o.getTheImportantInt()).thenReturn("1"); 

     // test code goes here 
} 
+0

我修改了我的示例,我確實需要使用field1對field20進行一些操作,但在測試方法中,這是不重要的。 – jasonfungsing 2014-10-02 05:25:48

+0

那麼,這取決於。如果你對field1和field20所做的操作會影響你在測試中檢查的結果,你別無選擇,只能模擬這些值。否則,您仍然可以忽略它們,畢竟您對測試感興趣的所有內容都不受其影響。另一方面,如果你有一個擁有20個getter的類,那麼你應該考慮改進你的設計(即使它是一個實體類,可能值得重新設計數據庫表以包含更少的列,因爲SQL DB中的長行會顯着地降低性能在大多數數據庫中)。 – eitanfar 2014-10-02 05:28:51

+0

我感覺很幸運,這20個getters對象是一個來自第三方rest API調用的json響應映射類:-) – jasonfungsing 2014-10-02 05:31:25