1

I wrote a test that uses Mockito 1.9.5. I have an HttpGet and an HttpPost which an HttpClient execute, and I'm testing to verify that the response from each returns the expected result in the form of an input stream.

The issue is that while using Mockito.when(mockedClient.execute(any(HttpPost.class))).thenReturn(postResponse) and Mockito.when(mockedClient.execute(any(HttpGet.class))).thenReturn(getResponse), where the responses are different objects, mockedClient.execute() always returns getResponse.

The test I've written is below:

private InputStream       postContent;
private InputStream       getContent;
@Mock
private FilesHandler hand;
@Mock
private MockHttpClient    client;
private MockHttpEntity    postEntity;
private MockHttpEntity    getEntity;
private MockHttpResponse  postResponse;
private MockHttpResponse  getResponse;
private String imgQuery = "someQuery";
private ParametersHandler ph;
private FileHandlerImpl   fileHand;
private String            indexFolder = "src/test/resources/misc/";
private String            indexFile   = "index.csv";

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
    try {
        postContent = new FileInputStream(indexFolder + "testContent.txt");
        postEntity = new MockHttpEntity(postContent);
        postResponse = new MockHttpResponse(postEntity, new BasicStatusLine(new ProtocolVersion("http", 1, 1), 200, "postReasonPhrase"));
        getContent = new FileInputStream(indexFolder + "testContent.txt");
        getEntity = new MockHttpEntity(getContent);
        getResponse = new MockHttpResponse(getEntity, new BasicStatusLine(new ProtocolVersion("http", 1, 1), 200, "getReasonPhrase"));
        ph = new ParametersHandler();
        fileHand = new FileHandlerImpl(client, ph, indexFolder, indexFile);
    } catch (Exception e) {
        failTest(e);
    }
}
@Test
public void getFileWhenEverythingJustWorks() {

    try {
        Mockito.when(client.execute(Mockito.any(HttpPost.class))).thenReturn(postResponse);
        Mockito.when(client.execute(Mockito.any(HttpGet.class))).thenReturn(getResponse);
        fileHand.getFile(hand, imgQuery, ph, "I");
        Mockito.verify(hand).rebuildIndex(Mockito.any(String.class), Mockito.any(Map.class), Mockito.any(Map.class), hand);
    } catch (IOException e) {
        failTest(e);
    }
}

A shortened version of the method being tested is below.

public void getFile(FilesHandler fileHandlerFl, String query, ParametersHandler ph, String type) {

        JsonFactory factory = new JsonFactory();
        HttpPost post = preparePost(query, factory);
        CloseableHttpResponse response = client.execute(post);

    String uri = "https://someuri.com" + "/File";
        HttpGet get = new HttpGet(uri);
        setParameters(get);
        response.close();
        response = client.execute(get);
}

As always, any help you can provide is appreciated.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
DivDiff
  • 963
  • 2
  • 10
  • 22

1 Answers1

3

Despite what it would mean when read in English, in Mockito 1.x, any(HttpGet.class) matches any value and not just any HttpGet. The parameter is only used to save a cast previous to Java 8.

From the Matchers.any(Class) documentation:

Matches any object, including nulls

This method doesn't do type checks with the given parameter, it is only there to avoid casting in your code. This might however change (type checks could be added) in a future major release.

Use isA(HttpGet.class) and isA(HttpPost.class) instead, and see Brice's comment below about future changes to the any(Class<?> clazz) matcher.

Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • 1
    For historical reference, `any` is a shorthand alias of `anything`, at that time the API was forcing one to cast, and contributors and/or commiters thought about passing the class as a param to avoid this cast, without changing the semantic of this API. However this change eventually modified what people thought that this API was doing. **This will be fixed in mockito 2+** – bric3 Nov 26 '15 at 10:12
  • @Brice Thanks for the information! Updating this answer and a few others on SO. – Jeff Bowman Nov 26 '15 at 20:05
  • I know this is several years old now but we recently ran into a similar problem. Another solution that worked for us was to chain `thenReturn` calls, knowing the order in which the calls were made. For example, `when (httpClient.execute(Mockito.any())).thenReturn(getResponse).thenReturn(putResponse);` I like the `isA` as a better solution but thought I'd add the one we found that worked as well. – Matt Crysler Jun 03 '19 at 23:15