2013-05-06 18 views
5

Ho la seguente classe:PowerMockito: come simulare i metodi chiamati dal costruttore?

public class Foo { 

    public Foo() { 
    initField1(); 
    initField2(); 
    initField3(); 
    } 

} 

ho bisogno di modificare il comportamento (per prendere in giro) initField1() e initField3() per loro fare non fare nulla o qualcos'altro che fanno effettivamente. Sono interessato ad eseguire il codice effettivo di initField2().

voglio scrivere il seguente test:

Foo foo = new Foo(); 
assertTrue(foo.myGet()); 

myGet() restituisce un attributo di Foo che è stato calcolato da initField2().

I metodi initField() sono ovviamente privati.

Come posso fare una cosa del genere?

Grazie per il vostro aiuto e cordiali saluti.

risposta

-1

Penso che ci sia qualcosa di sbagliato in quello che vuoi fare.

Per quanto ho capito, un framework beffardo come Mockito o PowerMock è pensato per simulare l'interazione tra l'oggetto in prova e le sue dipendenze.

Come ho capito la tua domanda, vuoi prendere in giro parte del comportamento dell'oggetto e testare il resto.

Nel tuo caso, si desidera verificare qualcosa che non accadrà mai, come initField2() non verrà mai chiamato senza chiamate a initField1() e initField3()

Se la ragione per cui non si vuole chiamare initField1() e initField3 è perché questi i metodi interagiscono con altri oggetti, o con filesystem o DB, quindi dovresti iniettare le dipendenze tramite l'argomento costruttore o setter annotati, e solo iniezioni di mock per i tuoi test. E per istanziare il tuo oggetto con le sue dipendenze correttamente configurate, usa il modello factory, il pattern builder, o anche meglio, usa un framework di injection dependency come quello di Spring o Google Guice.

Se il motivo che d'ont desidera chiamare initField1() e initField3 è perché hanno a che fare con la logica di business diverso nel vostro oggetto, allora questo odori (come in http://martinfowler.com/books/refactoring.html) come si sta rompendo il principio singola responsabilità, e si dovrebbe refactoring.

+0

Questo è un codice legacy. Preferisco non modificare la classe in esame scrivendo un nuovo costruttore che accetta argomenti per esempio. Voglio solo 'initField2()' per essere eseguito perché è responsabile per l'impostazione del campo che voglio testare. Non sono interessante nel testare il resto della logica del costruttore. –

+0

Mockito è pensato per simulare l'interazione, PowerMock è pensato per deridere il funzionamento interno parziale di una classe per il codice legacy, quindi questa risposta è semplicemente sbagliata. – eis

5

Considerando tutto può succedere nel codice legacy :) è possibile utilizzare PowerMock a reprimere metodi descritti nel http://code.google.com/p/powermock/wiki/SuppressUnwantedBehavior

import static org.powermock.api.support.membermodification.MemberMatcher.methods; 
import static org.powermock.api.support.membermodification.MemberModifier.suppress; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Foo.class) 
public class FooTest { 

    @Test 
    public void testSuppressMethod() throws Exception { 
     suppress(methods(Foo.class, "initField1", "initField3")); 
     Foo foo = new Foo(); 
    } 
} 

Ancora, si dovrebbe ri-fattore della classe dopo che hai un'adeguata copertura di test per esso .

+0

Grazie mille. Ora funziona! Un'altra domanda, come posso verificare che sia stato chiamato 'initField2()'? Ho pensato di spiare il mio nuovo Foo, ma non c'è in realtà alcuna interazione con esso così 'verifyPrivate (foo) .invoke (initField2)' non aiuta. –

+0

@JulienCollah lo verificherete indirettamente controllando che 'foo.myGet()' restituisca un valore corretto. –

Problemi correlati