3

I am writing a JUnit test case using Mockito to test for JSONParseException but i am getting ClassCastException. It seems like the peoblem is in the line

 when(response.readEntity(Mockito.any(Class.class))).thenReturn(baseModel);

Below is my Mock class.

public class MockJerseyClient {

private ClientConfiguration clientConfig;
private Client client;
private WebTarget webTarget;
private Invocation.Builder invocationBuilder;
private Response response;
private StatusType statusType;
private String myString = null;

public enum CATEGORY {
    XML, JSON
}

private JAXBContext getContext(BaseModel baseModel) throws JAXBException {

    if (baseModel instanceof RetrieveBillingResponse) {
        return JAXBContext.newInstance(RetrieveBillingResponse.class);
    } else if (baseModel instanceof ThirdPartyVinResponse) {
        return JAXBContext.newInstance(ThirdPartyVinResponse.class);

    }
    return null;
}

public MockJerseyClient(String URI, int status, String contentType, BaseModel baseModel, CATEGORY responseType) throws EISClientException, Exception {

    if (responseType == CATEGORY.XML) {

        JAXBContext context = getContext(baseModel);
        Marshaller marshallerObj = context.createMarshaller();
        marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        marshallerObj.marshal(baseModel, byteOut);

        // myString = byteOut.toString();
        // System.out.println(myString);

    } else if (responseType == CATEGORY.JSON) {

        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(stream, baseModel);

    }

    clientConfig = mock(ClientConfiguration.class);
    client = mock(Client.class);
    clientConfig.createClient();

    webTarget = mock(WebTarget.class);
    clientConfig.createWebResource(URI);

    response = mock(Response.class);

    invocationBuilder = mock(Invocation.Builder.class);

    statusType = mock(StatusType.class);

    when(client.target(URI)).thenReturn(webTarget);

    when(clientConfig.createWebResource(anyString())).thenReturn(webTarget);

    when(webTarget.path(anyString())).thenReturn(webTarget);
    when(webTarget.queryParam(anyString(), anyString())).thenReturn(webTarget);
    when(webTarget.register(RetrieveBillingResponseXMLReader.class)).thenReturn(webTarget);
    when(webTarget.request()).thenReturn(invocationBuilder);

    when(invocationBuilder.header(anyString(), Mockito.any())).thenReturn(invocationBuilder);
    when(invocationBuilder.accept(anyString())).thenReturn(invocationBuilder);
    when(invocationBuilder.get(Response.class)).thenReturn(response);

    when(response.readEntity(Mockito.any(Class.class))).thenReturn(baseModel);
    when(response.getStatusInfo()).thenReturn(statusType);
    when(statusType.getStatusCode()).thenReturn(status);

}

public ClientConfiguration getClientConfig() {
    return clientConfig;
}
}

My JUnit test.

 @Test
public void testRetrieveBillingJSONParseException() throws   EISClientException, Exception {

    RetrieveEnhancedBillingSummaryResponse entity = new RetrieveEnhancedBillingSummaryResponse();
    MockJerseyClient mockClient = new MockJerseyClient("mig", 200, "application/json", entity, CATEGORY.JSON);

    EISBillingClient client = new EISBillingClient(mockClient.getClientConfig(), "url");
    RetrieveBillingServiceRequest request = client.getRetrieveBillingRequest();
    request.setAccepts(ContentType.JSON);
    request.setParameters(client.getRetrieveBillingRequestParameters("HO123456789", "11302015"));

    boolean caughtException = false;
    try {

        @SuppressWarnings("unused")
        RetrieveBillingServiceResponse response = client.retrieveBilling(request);

    } catch (Exception ex) {
        if (ex instanceof EISClientException) {
            caughtException = true;
            assertEquals("Exception in processing the Retrieve Billing Call", ex.getMessage());
            assertTrue(ex.getCause() instanceof JsonParseException);
        } else {
            ex.printStackTrace();
            fail("Target exception other than JsonParseException.");
        }
    }
    assertTrue(caughtException);
 }

Thanks,

4
  • 1
    Please add exception stack trace Commented Dec 1, 2015 at 17:08
  • Below is the stack trace. java.lang.ClassCastException: mig.eis.model.response.RetrieveEnhancedBillingSummaryResponse cannot be cast to mig.eis.model.response.RetrieveBillingResponse at mig.eis.client.billing.EISBillingClient.retrieveBilling(EISBillingClient.java:110) at test.mig.eis.client2.billing.TestEISBillingClient2.testRetrieveBillingJSONParseException(TestEISBillingClient2.java:274) Commented Dec 1, 2015 at 17:19
  • @Mukul Goel. Am I doing anything wrong while mocking? Commented Dec 1, 2015 at 17:43
  • 2
    @syed: It is better if you edit your question to add the stack trace, and format it like code. Also, your question contains much code so it takes some work to look through and understand. If you can post a smaller example with the same problem maybe more people will take the time to help you. Commented Dec 1, 2015 at 19:03

1 Answer 1

2

It looks like you're returning a RetrieveEnhancedBillingSummaryResponse baseModel where your system under test is expecting a RetrieveBillingResponse. Mockito won't catch that you're stubbing the wrong type, but it will still fail later.

Note that when you say:

when(response.readEntity(Mockito.any(Class.class))).thenReturn(baseModel);

You're saying that the baseModel will be returned no matter what class is passed into readEntity. Instead, you probably want a type check there, especially if you're using the same mocked response for multiple calls:

when(response.readEntity(baseModel.getClass()).thenReturn(baseModel);

This will return the baseModel if and only if the call to readEntity is trying to read an object of baseModel's class.

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

3 Comments

All my classes extend BaseModel, but while mocking, it doesn't allow me to return baseModel.
Of course! Note that readEntity takes a type parameter that guarantees that readEntity(Foo.class) will return a Foo or Foo subclass. Even if Foo extends BaseModel, you couldn't mock readEntity(Foo.class) to return an arbitrary BaseModel; Java will try to cast it to a Foo to match the signature, and failing that will cause a ClassCastException.
I got your point, but i have to return different classes which are the subclasses of BaseModel. The main purpose of this method is to check for the JSONParseException.

Your Answer

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