2014-10-02 15 views
12

Ho un problema quando si scrive test di unità con simulazione. C'è un oggetto che ho bisogno di prendere in giro con un sacco di getter, che li chiamo al codice. Tuttavia, quelli non sono lo scopo del mio test unitario. Quindi, c'è un modo per prendere in giro tutti i metodi invece di prenderli in giro uno alla volta.Mockito mock tutti i metodi chiamano e restituiscono

Ecco l'esempio di codice:

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;} 

} 

e questa è la classe di servizio ho bisogno di testare

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 

    } 
} 

all'interno della classe di test, il metodo di prova è come

@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 

} 

Quindi, c'è un modo per evitare di scrivere tutti i "quando" per l'inutile "campo1" a "campo20"

+0

Non è per se stai bene con il ritorno di loro nulla. –

+0

Ho bisogno di usarli nel metodo, mi dispiace per non inserire questo nell'esempio. – jasonfungsing

risposta

22

È possibile controllare le risposte predefinite della propria simulazione. Quando si crea il mock, utilizzare:

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

Non sono sicuro di aver compreso correttamente la risposta. Devo ancora impostare manualmente il valore predefinito per campo1 a campo20 nel metodo di risposta? – jasonfungsing

+2

@jasonfungsing No non lo fai. In questo caso stai impostando il comportamento predefinito del tuo oggetto deriso. Infatti, se chiami 'doReturn (...). When()' sostituirai questo comportamento predefinito con il nuovo stub personalizzato. Quindi è utile se è necessario modificare il comportamento di un metodo mentre altri ancora restituiscono i valori predefiniti. A proposito, ho aggiornato la mia risposta. – SimY4

+0

È anche possibile eseguire semplicemente 'mock (ObjectNeedToMock.class, RETURNS_DEFAULTS);' Non è necessario alcun lambda. – Amalgovinus

0

Se non siete interessati al risultato di getField1() ad getField20() in un particolare caso di test, non si deve deridere affatto. In altre parole, se tutti i test case specifico dovrebbe essere preoccupati è getTheImportantInt(), allora il vostro banco di prova dovrebbe essere simile a questo:

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

     // test code goes here 
} 
+0

Ho modificato il mio esempio, ho bisogno di fare qualcosa con field1 a field20, tuttavia questo non è un problema nel metodo di test. – jasonfungsing

+0

Bene, allora dipende. Se ciò che fai con field1 su field20 influenza il risultato che stai verificando nel test, non hai altra scelta che prendere in giro i valori. Altrimenti, puoi ancora ignorarli, dopotutto, tutto ciò che ti interessa non è influenzato da test. In una nota diversa, se hai una classe con 20 getter, dovresti davvero considerare di migliorare la tua progettazione (anche se è una classe entità, probabilmente vale la pena ridisegnare la tabella DB per contenere meno colonne, poiché le lunghe file nei DB SQL compromettono drasticamente le prestazioni nella maggior parte dei DB). – eitanfar

+0

Mi sento fortunato che questo oggetto di 20 getters è una classe di mappatura della risposta json da una chiamata api restful di terze parti :-) – jasonfungsing

Problemi correlati