Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

doAnswer for static methods - PowerMock

One of static method I am using, it does two things. It returns some data, but it also modifies the argument object that is passed to it. This updated argument object is then used later in code.

I am using PowerMock to mock the return behavior.

For defining the second part - updating the input argument, I am defining doAnswer method but it's not working. The method that I'm trying to test looks like this.

public void login() throws ConnectionException, AsyncApiException {
    ConnectorConfig partnerConfig = new ConnectorConfig();

    //This call sets the value in one member variable 'serviceEndPoint in ParterConfig which is accessed later in this method only.
    partnerConnection = Connector.newConnection(partnerConfig);

    //partnerConfig.getServiceEndpoint is called.

    PowerMockito.mockStatic(Connector.class);
    when(Connector.newConnection(Mockito.any(ConnectorConfig.class))).thenReturn(partnerConnection);

    PowerMockito.doAnswer(new Answer<Void>() {
        @Override
        public Void answer(InvocationOnMock invocation) {
            ConnectorConfig config = (ConnectorConfig) invocation.getArguments()[0];
            config.setServiceEndpoint("service end point");
            return null;
        }
    }).when(Connector.newConnection(Mockito.any(ConnectorConfig.class)));
}     

but above throws error saying 'Unfinished stubbing detected here'. Connector is a third party class so I don't have control over its behavior.

Any suggestions, what could be going wrong?

like image 559
RandomQuestion Avatar asked Aug 05 '13 23:08

RandomQuestion


1 Answers

PowerMockito.doAnswer(new Answer<Void>() {
    /* ... */
}).when(Connector.newConnection(Mockito.any(ConnectorConfig.class)));

Your when is the problem. In normal Mockito, using any doAnswer/doReturn/etc call, you have to place the call you're stubbing outside of the call to when, like so:

Mockito.doAnswer(new Answer<Void>() {
    /* ... */
}).when(yourMock).callVoidMethod();
//            ^^^^^^

PowerMockito further requires that calls to static methods happen in the next statement, like so:

PowerMockito.doAnswer(new Answer<Void>() {
    /* ... */
}).when(Connector.class); Connector.newConnection(/*...*/);
//                    ^^^^^^

Note that from 2009 (~1.3.x) to 2013 (~1.5.x), the docs were actually inconsistent, alluding to a zero-arg when despite all signatures requiring at least a class literal.

Obligatory PSA: It's generally a good idea to avoid mocking types you don't own, though opinions may vary on that one.

like image 123
Jeff Bowman Avatar answered Sep 23 '22 19:09

Jeff Bowman