简体   繁体   中英

Mockito - How to spy on Invocation argument in doAnswer

This is my first day writing Unit tests using Mockito and I might have started with a complex exercise.

Below is my class structure and I am writing tests for Class2.targetMethod(). Class1 static method modifies passed in object instead of returning any results.

class Class1 {
    static void dbquery(OutParam out) {
        // Complex code to fill in db results in OutParam object
    }
}

class Class2 {
    void targetMethod() {
        OutParam p1 = new OutParam1();
        Class1.dbquery(p1);
        ResultSet rs = p1.getCursor();
        ...
    }
}

Below is my setup for the tests:

@RunWith(PowerMockRunner.class)
@PrepareForTest({Class1.class, Class2.class})
public class Class2Test {
    @Before
    public void setUp() throws Exception {

        PowerMockito.mockStatic(Class1.class);

        doAnswer(new Answer<Void>() {
            @Override
            public Void answer(InvocationOnMock invocation) throws Exception {
                OutParam result = (OutParam)invocation.getArguments()[1];
                OutParam spy = spy(result);
                ResultSet mockResult = mock(ResultSet.class);
                doReturn(mockResult).when(spy.getCursor());
                when(mockResult.getString("some_id")).thenReturn("first_id","second_id");
                when(mockResult.getString("name")).thenReturn("name1","name2");

                return null;
            }
        }).when(Class1.class, "dbquery", any());
    }
}

However the tests fail with exception below - mainly due to "doReturn" line.

Any suggestions on this problem or if my approach is completely wrong.

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, you naughty developer!
 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed

The syntax for:

doReturn(mockResult).when(spy.getCursor());

should be:

doReturn(mockResult).when(spy).getCursor();

By calling when with only the spy , and not spy.getCursor() , you give Mockito a chance to temporarily deactivate getCursor so you can stub it without calling the real thing. Though that doesn't seem to be important here, Mockito insists that you keep this pattern for calls to when following doAnswer (etc).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM