4

I have the following method for which I'm trying to write unit test using Mockito. I'm fairly new to Mockito and trying to catch up.

Method to test

public synchronized String executeReadRequest(String url) throws Exception{

    String result = null;
    RestClient client = null;
    Resource res = null;
    logger.debug("Start executing GET request on "+url);

    try{
         client = getClient();
         res = client.resource(url);
         result = res.contentType(this.requestType).accept(this.responseType).get(String.class);
    }
    catch(Exception ioe){
        throw new Exception(ioe.getMessage());
    }
    finally{
        res = null;
        client = null;
    }

    logger.info("GET request execution is over with result : "+result);
    return result;
}

The unit test with Mockito

@Test
public void testRestHandler() throws Exception {
    RestHandler handler = spy(new RestHandler());
    RestClient mockClient = Mockito.mock(RestClient.class,Mockito.RETURNS_DEEP_STUBS); 
    Resource mockResource = Mockito.mock(Resource.class,Mockito.RETURNS_DEEP_STUBS);

    doReturn(mockClient).when(handler).getClient();
    Mockito.when(mockClient.resource(Mockito.anyString())).thenReturn(mockResource);

  //ClassCastException at the below line
    Mockito.when(mockResource.contentType(Mockito.anyString()).accept(Mockito.anyString()).get(Mockito.eq(String.class))).thenReturn("dummy read result");

    handler.setRequestType(MediaType.APPLICATION_FORM_URLENCODED);
    handler.setResponseType(MediaType.APPLICATION_JSON);
    handler.executeReadRequest("abc");
}

But I'm getting a ClassCastException at the line

Mockito.when(mockResource.contentType(Mockito.anyString()).accept(Mockito.anyString()).get(Mockito.eq(String.class))).thenReturn("dummy read result");

Exception

java.lang.ClassCastException: org.mockito.internal.creation.jmock.ClassImposterizer$ClassWithSuperclassToWorkAroundCglibBug$$EnhancerByMockitoWithCGLIB$$4b441c4d cannot be cast to java.lang.String

Appreciate any help to resolve this.

Many thanks.

2 Answers 2

3

This style of chaining during stubbing isn't correct:

Mockito.when(
    mockResource.contentType(Mockito.anyString())
        .accept(Mockito.anyString())
        .get(Mockito.eq(String.class)))
    .thenReturn("dummy read result");

Even though you've set the mocks to return deep stubs, Matchers work via side-effects, so this line doesn't achieve what you think it does. All three matchers (anyString, anyString, eq) are evaluated during the call to when, and the way you have it your code is likely to throw InvalidUseOfMatchersException at the slightest provocation—including adding unrelated code or verifications later.

This means your problem isn't the use of eq(String.class): It's that Mockito is trying to work the Class matcher in where it doesn't belong.

Instead, you'll need to stub specifically:

Mockito.when(mockResource.contentType(Mockito.anyString()))
    .thenReturn(mockResource);
Mockito.when(mockResource.accept(Mockito.anyString()))
    .thenReturn(mockResource);
Mockito.when(mockResource.get(Mockito.eq(String.class))) // or any(Class.class)
    .thenReturn("dummy read response");

Note that some of the difficulty here is that Apache Wink uses the Builder pattern, which can be laborious in Mockito. (I've returned mockResource here, but you could imagine returning specific other Resource objects, at the expense of requiring them in exactly that order later.) A better way might be to use a default Answer that returns this whenever possible.

Sign up to request clarification or add additional context in comments.

Comments

-2

Solved it by changing the get call to

get(Mockito.any(Class.class))

1 Comment

While this code may answer the question, it would be better to include some context, explaining how it works and when to use it. Code-only answers are not useful in the long run.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.