How to get coverage for anonymous class overridden methods using junit mockito

rupa :

I have below code to retry the request based on response code.

public class Sample {
    public static HttpClient getInstance() {
        HttpClientBuilder builder = HttpClients.custom();     
            builder.setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
                int waitPeriod = 200;

                @Override
                public boolean retryRequest(final HttpResponse response, final int executionCount,
                    final HttpContext context) {

                    int statusCode = response.getStatusLine().getStatusCode();
                    return ((statusCode == 429)&& (executionCount < 3));
                }

                @Override
                public long getRetryInterval() {
                    return waitPeriod;
                }
            });

        return builder.build();

    }
}

While I am writing the unit tests for this getInstance method the overridden methods (retryRequest, getRetryInterval) are not getting covered. How can I write the unit tests to get coverage for these methods as well. By googling I found we can use ArgumentCaptor. I have tried the below code, but it does not work.

import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;

import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ServiceUnavailableRetryStrategy;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HttpContext;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

@WebAppConfiguration
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:context.xml"})
@PrepareForTest({ HttpClients.class, Sample.class})
public class Sample {

    @Mock
    HttpClientBuilder clientBuilderMock;

    @Mock
    CloseableHttpClient clientMock;

    @Mock
    HttpResponse responseMock;

    @Mock
    HttpContext contextMock;

    @Mock
    StatusLine statusLineMock;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        PowerMockito.mockStatic(HttpClients.class);
    }

    @Test
    public void test() throws Exception {       
        when(HttpClients.custom()).thenReturn(clientBuilderMock);
        when(clientBuilderMock.build()).thenReturn(clientMock);
        when(responseMock.getStatusLine()).thenReturn(statusLineMock);
        when(statusLineMock.getStatusCode()).thenReturn(429);

        Sample.getInstance();

        ArgumentCaptor<ServiceUnavailableRetryStrategy> argumentCaptor = ArgumentCaptor.forClass(ServiceUnavailableRetryStrategy.class);
        verify(clientBuilderMock).setServiceUnavailableRetryStrategy(argumentCaptor.capture());
        ServiceUnavailableRetryStrategy retryStrategy = argumentCaptor.getValue();
        retryStrategy.retryRequest(responseMock, 3, contextMock);       
    }

}

argumentCaptor.capture() is always giving me null.I am getting like

org.mockito.exceptions.base.MockitoException: No argument value was captured! You might have forgotten to use argument.capture() in verify()... ...or you used capture() in stubbing but stubbed method was not called. Can anyone help me on this. I would like to test the retryRequest method functionality.

second :

Edit: rephrased the answer to make it easier to read.


  1. Classes that are supposed to be handeled by PowerMockito need to be declared in the @PrepareForTest annotation.

  2. If annotations are used to create the mocks all annotated classes which are not declared in the @PrepareForTest annotation, are created by Mockito.

  3. If annotations are used to create the mocks and MockitoAnnotations.initMocks(this); is called, this apparently causes the declaration to be overriden and all mocks are created by Mockito instead. (Source: https://groups.google.com/forum/#!topic/powermock/yPBey4hr7IU)

  4. Mockito can not handle static or final methods.
    The mocking operation might fail silently.


The root of your problem is that HttpClientBuilder#setServiceUnavailableRetryStrategy is a final method and therefore can not be handeled by Mockito.

The solution is that the Mock of HttpClientBulder has to be handeled by PowerMockito. In accordance with 1. it needs to be declared in the @PrepareForTest annotation.

@PrepareForTest({ HttpClients.class, HttpClientBuilder.class, Sample.class})


If you want to use Annotations to create the mocks, you must not call

MockitoAnnotations.initMocks(this);

(see 2. / I verified this issue with the latest powermockito versions (1.7.4 / 2.0.2))


Else you have to create the mock manually.

HttpClientBuilder clientBuilderMock = PowerMockito.mock(HttpClientBuilder.class);

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=162411&siteId=1
Recommended