thecatnapp
thecatnapp

Reputation: 11

Mockito method behavior

I have a factory interface B which returns objects of type A. Type A is also an interface.

I am having trouble figuring out how I can define method behavior for A.doSomething() in my mocks, because every time the factory returns a new instance of A, it needs to know how to doSomething().

This is what I have so far for mocking the factory, however A doesn't know how to doSomething().

when(B.getObject()).thenReturn(Mockito.mock(A.class));

Is there some sort of way I can define A.doSomething() for all instances of A which will be returned?

Any help is greatly appreciated.

Upvotes: 1

Views: 1084

Answers (3)

Adrian Shum
Adrian Shum

Reputation: 40036

As a mock factory, your SUT normally shouldn't care about whether it is a "new instance" everytime.

Hence, what you need to do is simply:

B mockFactory = mock(B.class);
A mockA = mock(A.class);
when(mockFactory.getObject()).thenReturn(mockA);
when(mockA.doSomething()).thenReturn(123);

// Call your SUT, and then whenever the factory's getObject() is called, 
// it will return the same mockA, and when mockA.doSomething() is called,
// it will always return 123.

Of course you can use doAnswer() and return a new mock A everytime. However, you will be difficult to verify the interaction with your As.

Upvotes: 0

thecatnapp
thecatnapp

Reputation: 11

In case someone else runs into a similar situation, this is what ended up working for me after playing around with thenAnswer() as suggested in the comments.

private static A createA() {
    A a = Mockito.mock(A.class);
    when(a.doSomething()).thenReturn(...);
    return a;
}

when(B.getObject()).thenAnswer(new Answer<A>(){

            @Override
            public A answer(InvocationOnMock invocation) throws Throwable {
                A a = createA();
                return a;
            }

        });

Upvotes: 0

Dragan Bozanovic
Dragan Bozanovic

Reputation: 23552

A a = createA();
when(B.getObject()).thenReturn(a);

private static A createA() {
  A result = Mockito.mock(A.class);
  when(A.doSomething()).thenReturn(something);
  return result;
}

You may be tempted to try something like:

when(B.getObject()).thenReturn(createA());

but it will not work because of 'nested' mocking. More details here.

Upvotes: 1

Related Questions