Question

I am trying to test a static method using JMockit. This method uses a utility class static method.

When the test runs, JMockit complains and throws the following exception:

    Test set: com.company.pkg.subpkg.mylib.test.ServiceCommunicationTest
    --------------------------------------------------------------------
    Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.086 sec  FAILURE!
    testMakeResourceRequestPositive(com.company.pkg.subpkg.mylib.test.ServiceCommunicationTest)  Time elapsed: 0.085 sec   ERROR!
    mockit.internal.UnexpectedInvocation: Parameter "requestToSend" of com.company.pkg.subpkg.mylib.NetworkUtil#sendHttpRequest(org.apache.http.client.methods.HttpUriRequest requestToSend) expected GET https://localhost HTTP/1.1, got GET https://localhost HTTP/1.1
        at com.company.pkg.subpkg.mylib.NetworkUtil.sendHttpRequest(NetworkUtil.java)
        at com.company.pkg.subpkg.mylib.serviceaccess.client.ServiceCommunicator.makeResourceRequest(ServiceCommunicator.java:57)
        at com.company.pkg.subpkg.mylib.test.ServiceCommunicationTest.testMakeResourceRequestPositive(ServiceCommunicationTest.java:79)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:606)
        .    .    .
        .    .    .

Here is the test that is causing the exception to be thrown -



    @RunWith(JUnit4.class)
    public class ServiceCommunicationTest {

        @Mocked
        private NetworkUtil _mockedNetworkUtil;

        @Test
        public void testMakeResourceRequestPositive() throws IOException {

            ResourcesDTO resDto = null;
            final String jsonResponse = JsonResponsesTestUtil.SUCCESSFUL_RESOURCES_RESPONSE;

            final String serviceUrl = "https://localhost";
            final HttpUriRequest requestToSend = new HttpGet(serviceUrl);

            new Expectations() {
                {
                    NetworkUtil.validateStringInput(serviceUrl, "rootUri");

                    NetworkUtil.sendHttpRequest(requestToSend);
                    returns(jsonResponse);
                }
            };

            // Make the actual call …
            try {
                resDto = ServiceCommunicator.makeResourceRequest(serviceUrl);
            } catch (IOException e) {
                Assert.fail("Failed to parse/obtain the Resources DTO: " + e.getMessage());
            }

            Assert.assertNotNull(resDto);
            Assert.assertNotNull(resDto.getSelfUri());
        }
    }


Some thing which is confusing is that the expected and actual strings (as reported in the exception) as same -

expected GET https://localhost HTTP/1.1
     got GET https://localhost HTTP/1.1

The method under test is here -

public static ResourcesDTO makeResourceRequest(String rootUri) throws IOException {

    NetworkUtil.validateStringInput(rootUri, "rootUri");

    // Preparing HTTP Request ...
    HttpUriRequest requestToSend = new HttpGet(rootUri);

    // Headers that needs to be set ...
    requestToSend.addHeader(HttpHeaders.ACCEPT,       MimeConstants.CONTENT_TYPE_STRING);

    // Send Request to Authorization Service ...
    String response = NetworkUtil.sendHttpRequest(requestToSend);

    // Got the response, construct a DTOs out of it ...
    StringReader reader = new StringReader(response);

    // Convert the JSON response to appropriate DTO ...
    ObjectMapper mapper = new ObjectMapper();
    ResourcesDTO resourcesDto = mapper.readValue(reader, ResourcesDTO.class);

    return resourcesDto;
}

The utility class that is referred by the above method is this -



    public final class NetworkUtil {

        // Prevent Instance Creation …
        private NetworkUtil() {
        }

        public  static  ResourcesDTO  makeResourceRequest(String  rootUri)  throws  IOException {

            NetworkUtil.validateStringInput(rootUri, "rootUri");

            // Preparing HTTP Request ...
            HttpUriRequest requestToSend = new HttpGet(rootUri);

            // Headers that needs to be set ...
            requestToSend.addHeader(HttpHeaders.ACCEPT,   MimeConstants.CONTENT_TYPE_STRING);

            // Send Request to the Server ...
            String response = NetworkUtil.sendHttpRequest(requestToSend);

            // Got the response, construct a DTOs out of it ...
            StringReader reader = new StringReader(response);

            // Convert the JSON response to appropriate DTO ...
            ObjectMapper mapper = new ObjectMapper();
            ResourcesDTO resourcesDto = mapper.readValue(reader, ResourcesDTO.class);

            return resourcesDto;
        }
    }

Can anyone see what's going on here ?

Was it helpful?

Solution

Finally, I was able to nail down the reason of this Unexpected Invocation exception.

NetworkUtil.sendHttpRequest((HttpUriRequest) any);
returns(jsonResponse);

Like shown above, I changed the line just before returns, in the Expectations block. Instead of passing an object of type HttpUriRequest, now I told JMockit that any object of type HttpUriRequest is acceptable.

I believe, JMockit performs an equals() on the parameters of mocked API calls. The problem here may be that HttpUriRequest deosn't implement an equals() method of its own, instead it inherites from Object. Which means that it is essentially doing an object1 == object2.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top