Mockito: Is there a way to capture the return value of a stubbed method?

If I make fun of a method to return a new instance of an object, how can I capture the returned instance?

eg:.

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

Obviously, I can have a field of type Foo and inside the answer set it to a new instance, but is there a better way? Something like ArgumentCaptor?

+7
source share
2 answers

It looks like you want to observe the instances of Answer and get notfications every time the Answer method is called (which starts creating a new Foo ). So why not come up with the ObservableAnswer class:

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

Intended Use:

 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]) } }); 
+7
source

I wanted to do something similar, but with a spy object, not a layout. In particular, given the spy object, I want to commit the return value. Based on Andreas_D answer, here is what I came up with.

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

Intended Use:

 // 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 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 */); 
+9
source

All Articles