2014-04-23 6 views
18

Ho una classe A che deve essere testata. Quanto segue è la definizione di A:Utilizzo di Mockito per deridere una variabile locale di un metodo

public class A { 
    public void methodOne(int argument) { 
     //some operations 
     methodTwo(int argument); 
     //some operations 
    } 

    private void methodTwo(int argument) { 
     DateTime dateTime = new DateTime(); 
     //use dateTime to perform some operations 
    } 
} 

Ed in base al valore dateTime alcuni dati devono essere manipolati, recuperati dal database. Per questo database, i valori vengono mantenuti tramite un file JSON.

Questo complica le cose. Ciò di cui ho bisogno è impostare dateTime in una data specifica durante il test. C'è un modo per prendere in giro il valore di una variabile locale usando mockito?

+0

possibile duplicato di [Metodi di simulazione di oggetti di ambito locale con Mockito] (http://stackoverflow.com/questions/6520242/mocking-methods-of-local-cope-objects-with-mockito) – zubergu

+0

Nessuno degli altri le domande che ho trovato su questo argomento avevano lo strato aggiuntivo di astrazione. Inoltre, la maggior parte di essi ha istanziato la variabile locale tramite un metodo della classe derisa. – user657592

risposta

18

Non è possibile prendere in giro una variabile locale. Che cosa si potrebbe fare, però, è estratto la sua creazione a un metodo protected e spy esso:

public class A { 
    public void methodOne(int argument) { 
    //some operations 
    methodTwo(int argument); 
    //some operations 
    } 

    private void methodTwo(int argument) { 
    DateTime dateTime = createDateTime(); 
    //use dateTime to perform some operations 
    } 

    protected DateTime createDateTime() { 
    return new DateTime(); 
    } 
} 

public class ATest { 
    @Test 
    public void testMethodOne() { 
    DateTime dt = new DateTime (/* some known parameters... */); 
    A a = Mockito.spy(new A()); 
    doReturn(dt).when(a).createDateTime(); 
    int arg = 0; // Or some meaningful value... 
    a.methodOne(arg); 
    // assert the result 
} 
+6

Non desidero scrivere un metodo protetto createDateTime(). Non c'è altro modo per farlo? – user657592

+0

In realtà è necessario utilizzare Mockito.doReturn (dt) .Quando (a) .createDateTime() Si veda https://stackoverflow.com/questions/11620103/mockito-trying-to-spy-on-method-is-calling -il metodo-originale – Alex

+1

Ovviamente è corretto @Alex, grazie per aver notato! Modificato e risolto. – Mureinik

2

Il metodo migliore per affrontare tale problema è quello di usare un iniettato Clock servizio utilizzato per ottenere nuove istanze di DateTime . In questo modo, il test può iniettare un finto orologio, che restituisce un DateTime specifico anziché l'ora corrente.

Notare che il nuovo Java 8 time API definisce tale Clock class, appositamente per tale scopo.

+0

Ciò richiede un jdk1.8, giusto? Sono attualmente in 1.7 e non ho intenzione di eseguire l'aggiornamento in qualsiasi momento presto. – user657592

+1

No. È sufficiente definire la propria classe o interfaccia Clock e chiamare 'clock.newDateTime()' invece di 'new DateTime()' per ottenere l'ora corrente. –

Problemi correlati