2011-08-31 19 views
7

Si me burlo de un método para devolver una nueva instancia de algún objeto, ¿cómo puedo capturar la instancia devuelta?mockito: ¿Hay alguna manera de capturar el valor de retorno del método stubbed?

ej .:

when(mock.someMethod(anyString())).thenAnswer(new Answer() { 
    Object answer(InvocationOnMock invocation) { 
     Object[] args = invocation.getArguments(); 
     Object mock = invocation.getMock(); 
     return new Foo(args[0]) 
    } 
}); 

Obviamente, puede tener un campo de tipo Foo y en el interior answer configurarlo para que la nueva instancia, pero hay una manera más agradable? Algo como ArgumentCaptor?

Respuesta

6

Parece que desea observar continuación Answer casos y recibir notfications cada vez que el método se llama answer (que desencadena la creación de un nuevo Foo). ¿Por qué no inventar una clase ObservableAnswer: uso

public abstract class ObservableAnswer implements Answer { 
    private Listener[] listeners; // to keep it very simple... 

    public ObservableAnswer(Listener...listeners) { 
    this.listeners = listeners; 
    } 

    @Override 
    public Object answer(InvocationOnMock invocation) { 
    Object answer = observedAnswer(invocation); 
    for (Listener listener:listeners) { 
     listener.send(answer); 
    } 
    return answer; 
    } 

    // we'll have to implement this method now 
    public abstract Object observedAnswer(InvocationOnMock invocation); 
} 

previsto:

Listener[] myListenerns = getListeners(); // some magic (as usual) 
when(mock.someMethod(anyString())).thenAnswer(new ObservableAnswer(myListeners) { 
    Object observedAnswer(InvocationOnMock invocation) { 
     Object[] args = invocation.getArguments(); 
     Object mock = invocation.getMock(); 
     return new Foo(args[0]) 
    } 

}); 
9

que quería hacer algo similar, pero con un objeto espiado en lugar de una maqueta. Específicamente, dado un objeto espía, quiero capturar el valor de retorno. Basado en la respuesta de Andreas_D, esto es lo que se me ocurrió.

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

intención de uso:

// spy our dao 
final Dao spiedDao = spy(dao); 
// instantiate a service that does some stuff, including a database find 
final Service service = new Service(spiedDao); 

// let's capture the return values from spiedDao.find() 
final ResultCaptor<QueryResult> resultCaptor = new ResultCaptor<>(); 
doAnswer(resultCaptor).when(spiedDao).find(any(User.class), any(Query.class)); 

// execute once 
service.run(); 
assertThat(resultCaptor.getResult()).isEqualTo(/* something */); 

/// change conditions /// 

// execute again 
service.run(); 
assertThat(resultCaptor.getResult()).isEqualTo(/* something different */); 
Cuestiones relacionadas