2011-08-17 8 views
6

Ho ottenuto una classe utilizzando una factory per la creazione di alcuni oggetti. Nel mio test di unità vorrei accedere al valore di ritorno della fabbrica. Poiché la factory viene passata direttamente alla classe e non viene fornito alcun getter per l'oggetto creato, è necessario intercettare la restituzione dell'oggetto dalla fabbrica.Mockito + Spy: come ottenere i valori di ritorno

RealFactory factory  = new RealFactory(); 
RealFactory spy   = spy(factory); 
TestedClass testedClass = new TestedClass(factory); 

// At this point I would like to get a reference to the object created 
// and returned by the factory. 

Esiste la possibilità di accedere al valore di ritorno della fabbrica? Probabilmente stai usando la spia?
L'unico modo che posso vedere è prendere in giro la fabbrica di creare metodo di ...

saluti

+0

Perché dovrebbe 'TestedClass' prendere in fabbrica come la dipendenza. Non dovrebbe semplicemente chiedere la classe effettiva creata dalla fabbrica. ? (Law of Demeter) –

+0

Il 'TestedClass' è un componente OSGi. Un metodo del componente richiede ogni invocazione di un nuovo oggetto creato dalla fabbrica. Ho rifattorato la creazione dell'oggetto in una classe di fabbrica per fornire una migliore testabilità. Poiché l'oggetto creato viene inizializzato in base ai parametri del metodo, non è possibile passare semplicemente gli oggetti creati anziché quelli di fabbrica. –

risposta

1

L'approccio di scherno standard sarebbe di:

  1. Pre-creare l'oggetto che si desidera la fabbrica per tornare nel test case
  2. Creare un falso (o spia) della fabbrica
  3. Prescrivere la fabbrica di simulazione per restituire l'oggetto pre-creato.

Se si vuole veramente avere la RealFactory creare l'oggetto al volo, è possibile creare una sottoclasse e l'override del metodo fabbrica per chiamare super.create(...), quindi salvare il riferimento a un campo accessibili dalla classe di prova, quindi il ritorno l'oggetto creato.

24

Per prima cosa, si dovrebbe passare spy come argomento del costruttore.

A parte questo, ecco come si potrebbe fare.

public class ResultCaptor<T> implements Answer { 
    private T result = null; 
    public T getResult() { 
     return result; 
    } 

    @Override 
    public T answer(InvocationOnMock invocationOnMock) throws Throwable { 
     result = (T) invocationOnMock.callRealMethod(); 
     return result; 
    } 
} 

Destinazione d'uso:

RealFactory factory  = new RealFactory(); 
RealFactory spy   = spy(factory); 
TestedClass testedClass = new TestedClass(spy); 

// At this point I would like to get a reference to the object created 
// and returned by the factory. 


// let's capture the return values from spy.create() 
ResultCaptor<RealThing> resultCaptor = new ResultCaptor<>(); 
doAnswer(resultCaptor).when(spy).create(); 

// do something that will trigger a call to the factory 
testedClass.doSomething(); 

// validate the return object 
assertThat(resultCaptor.getResult()) 
     .isNotNull() 
     .isInstanceOf(RealThing.class); 
+0

Grazie per aver condiviso. IMHO: questa dovrebbe essere la risposta accettata. – BetaRide

Problemi correlati