2012-04-16 13 views
6

Mi piacerebbe usare Mockito unit test una classe astratta come dettagliato in questo great answer.Mocking di una classe astratta con un argomento di simulazione fittizio?

Il trucco è, la classe astratta ha una dipendenza da una strategia che viene iniettato nel suo costruttore. Ho creato una simulazione della strategia e mi piacerebbe che la mia istanza derisoria di BaseClass usasse la strategia derisoria per il mio test unitario.

Qualche suggerimento su come collegarlo? Al momento non utilizzo alcun framework IoC, ma sto considerando Spring. Forse farebbe il trucco?

// abstract class to be tested w/ mock instance 
abstract BaseClass 
{ 
    // Strategy gets mocked too 
    protected BaseClass(Strategy strategy) 
    { 
     ... 
    } 
} 

Aggiornamento:
Secondo la mailing list Mockito, c'è attualmente non è un modo per passare gli argomenti al costruttore di un mock.

risposta

4

Ho visto questo genere di cose fatte usando Mockito a un livello di contesto primaverile.

esempio:

<bean id="myStrategy" name="myStrategy" class="org.mockito.Mockito" factory-method="mock"> 
    <constructor-arg value="Strategy" /> 
</bean> 

Mi auguro che aiuta.

-1

Non è necessario fare nulla di speciale. Basta prendere in giro il fagiolo come normale:

Bean bean = mock(Bean.class); 
when(bean.process()).thenReturn(somethingThatShouldBeNamedVO); 

Proprio funziona :)

+0

Grazie, Giordania! Sfortunatamente, non penso che funzionerà per il mio caso dal momento che ho bisogno di uno specifico comportamento beffardo nella classe di strategia iniettata nella base. Se viene utilizzato un mock predefinito della strategia (che restituisce solo null, 0, ecc.), La logica della BaseClass derisa si interrompe. Grazie comunque! – HolySamosa

+0

Questo non risponde alla domanda. –

4

Ho finito solo utilizzando la riflessione per impostare un campo privato della mia classe di base, in questo modo:

// mock the strategy dependency 
Strategy strategyMock = mock(Strategy.class); 
when(....).thenReturn(...); 

// mock the abstract base class 
BaseClass baseMock = mock(BaseClass.class, CALLS_REAL_METHODS); 

// get the private streategy field 
Field strategyField = baseMock.getClass().getSuperclass().getDeclaredField("_privateStrategy"); 

// make remove final modifier and make field accessible 
Field modifiersField = Field.class.getDeclaredField("modifiers"); 
modifiersField.setAccessible(true); 
modifiersField.setInt(strategyField, strategyField.getModifiers() & ~Modifier.FINAL);   
strategyField.setAccessible(true); 

// set the strategy 
strategyField.set(baseMock, strategyMock); 

// do unit tests with baseMock 
... 

Sarebbe break se il nome del campo privato è mai cambiato, ma è commentato e io posso conviverci. È semplice, è una linea di codice e trovo preferibile esporre qualsiasi setter o dover sottoclassi esplicitamente nei miei test.

Modifica: Quindi non è più una riga di codice poiché il mio campo privato doveva essere 'finale', richiedendo un codice di riflessione aggiuntivo per aggirare.

+1

Ottimo post! Puoi fare tutto questo con una riga se hai una dipendenza Spring ;-). Ho trovato questa classe mentre ficcanasavo intorno alla scatola di chicche di Spring. 'org.springframework.test.util.ReflectionTestUtils.setField (baseMock," _privateStrategy ", strategyMock)' –

Problemi correlati