Mockito + Spy: How to gather return values

Marc-Christian Schulze picture Marc-Christian Schulze · Aug 17, 2011 · Viewed 18.1k times · Source

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.

Answer

Jeff Fairley picture Jeff Fairley · Sep 5, 2014

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