Search code examples
junitmockitojava-7spy

In Mockito, what's the proper way to return different results upon conseuctive calls to a non-static method?


I'm using Mockito 1.10.18 with Java 7. How do I mock different results upon consecutive calls to a non-static method? The API for the call I want to mock looks like

QueryResult query(String query)

So I set up the mock call in my JUnit test like so ...

    connection = Mockito.spy(connection);
    ReflectionTestUtils.setField(m_regOrderItemDao, "connection", connection);
...
Mockito.when(connection.query(Mockito.anyString())).thenReturn(queryResults1, queryResults2);

Although I can see that "connection" is of type "com.sforce.soap.enterprise.EnterpriseConnection$$EnhancerByMockitoWithCGLIB$$8011e13c@62e8ef9f" (so it is properly cast as a mock), the above is resulting in an exception ...

[MalformedQueryFault [ApiQueryFault [ApiFault  exceptionCode='MALFORMED_QUERY'
 exceptionMessage='SOQL statements cannot be empty or null'
 extendedErrorDetails='{[0]}'
]
 row='-1'
 column='-1'
]
]

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)

It is as if

connection.query(Mockito.anyString())

is somehow getting executed for real. What's the right way (and simple) way to set things up such that my mock returns the proper results upon each consecutive call?


Solution

  • Mockito.when(connection.query(Mockito.anyString())).thenReturn(queryResults1).thenReturn(queryResults2);
    

    Since you dont want the query to be executed you should use this format doReturn(...).when(..).

    Mockito.doReturn(queryResults1).doReturn(queryResults2).when(connection).query(Mockito.anyString())
    

    There is no difference between the above statements if you mock the oject. But if you are using spy, When(...).thenReturn() will call the real method first before returning. So you should use doReturn(...).when(..) in this case.
    More about it here