0

I'm trying to mock org.apache.http.impl.client.DefaultHttpClient using jmockit

I specially interested in mocking method DefaultHttpClient.execute() I cannot seem to figure out why it doesn't work. I can confirmed that jmockit work fine for other class and method that I mocked.

Below is a sample of the code. Can anyone tell me why the mocking of org.apache.http.impl.client.DefaultHttpClient does not work?

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import mockit.Injectable;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HttpContext;
import org.junit.Before;
import org.junit.Test;

import com.protecode.authenticationmodule.login.Login;

@SuppressWarnings("deprecation")
public class QueryTester2 {
    @Mocked HttpUriRequest uriRequest;
    @Injectable HttpContext context;

    @Before
    public void init() {

        new MockLoginClass2();
        new MockDefaultHttpClient2();
    }

    @Test
    public void QueryTester2_Test1() {

        try {

            // Works! True, or whatever the mocked value below
            System.out.println(Login.isLdapUser("john"));

            HttpClient c = new DefaultHttpClient();

            // Failed! Still prints "org.apache.http.impl.client.DefaultHttpClient@44f54792"
            // instead of "mockedResponseToString"
            System.out.println(c.toString());

            //Failed! I don't see the println of "Mocked DefaultHttpClient.execute"

            c.execute(uriRequest, context);



        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

// Mocks
@SuppressWarnings("deprecation")
class MockDefaultHttpClient2 extends
        MockUp<org.apache.http.impl.client.DefaultHttpClient> {
    @Mock
    public String toString() {
        System.out.println("mockedResponseToString");
        return "mockedResponseToString";
    }

    @Mock
    public HttpResponse execute(HttpUriRequest httpPost, HttpContext context)
            throws IOException, ClientProtocolException {
        System.out.println("Mocked DefaultHttpClient.execute");
        HttpServletResponse response = (HttpServletResponse) new org.eclipse.jetty.client.HttpResponse(
                null, null);
        return (HttpResponse) response;
    }
}

class MockLoginClass2 extends MockUp<Login> {
    @Mock
    protected static boolean isLdapUser(final String username) {
        return true;
    }
}
RonPringadi
  • 1,294
  • 1
  • 19
  • 44
  • 1
    I don't think @Mock can be on a static method, but I might be wrong – Novaterata Apr 26 '17 at 14:20
  • Why are you creating all those fully implemented types instead of using `@Mocked` or `@Injectable` with Expectations blocks – Novaterata Apr 26 '17 at 14:21
  • And you should actually use the instances of the MockUps, you are just creating them in Before then ignoring them – Novaterata Apr 26 '17 at 14:22
  • @Novaterata [1] The `@Mock` can work on the static method. See `Login.isLdapUser()` [2] Thanks that is quite true, I updated the code to use the `@Mocked`, old habbit die hard. [3] If you are referring to the init method, my understanding is we need to instantiate them before the Mocked class "replaces" the original class. The real Login is called everywhere in my code. I need a mocked class to replace the original ones. What you see is a simplified version. – RonPringadi Apr 26 '17 at 14:47
  • You can mock a static method, but the method in the MockUp shouldn't be static http://stackoverflow.com/questions/26408253/how-to-mock-a-static-method-from-jmockit – Novaterata Apr 26 '17 at 15:29
  • I don't think that's my question though ... any idea why I cannot mock `org.apache.http.impl.client.DefaultHttpClient` ? – RonPringadi Apr 26 '17 at 16:00
  • That's why it's a comment and not an Answer ;) jmockit is pretty particular and when things aren't right it doesn't always tell you. You could try filing a bug on github and maybe rogerio will see it right away. I'm speaking from experience as I couldn't use File in a MockUp for awhile due to a bug – Novaterata Apr 26 '17 at 17:21

1 Answers1

0

It seems that I made a mistake in my code above. Jmockit does not execute the mocked method because the signature that I gave is faulty.

@Mock
public HttpResponse execute(HttpUriRequest httpPost, HttpContext context)  throws IOException, ClientProtocolException {

After changing it to the following code, jmockit successfully mocked or "replace" the original method.

@Mock
public CloseableHttpResponse execute(HttpUriRequest httpReq, HttpContext context) throws IOException, ClientProtocolException {
RonPringadi
  • 1,294
  • 1
  • 19
  • 44