Search code examples
javamockitospy

Mockito + Spy: How to gather return values


I got a class using a factory for creating some object. In my unit test I would like to access the return value of the factory. Since the factory is directly passed to the class and no getter for the created object is provided I need to intercept returning the object from the factory.

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.

Is there a possibility to access the return value of the factory? Probably using the spy?
The only way I can see is to mock the factory create method.


Solution

  • First thing, you should be passing spy in as the constructor argument.

    That aside, here's how you could do it.

    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 usage:

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