使用GUICE注入HttpClient以在Java中获取模拟响应

时间:2014-08-22 19:43:32

标签: java unit-testing junit httpclient guice

我是新手和注射剂。在编写单元测试时需要帮助。

我有一个通过发出GET请求来获取会话令牌的方法  

    String strTemp = "";
        String sessionToken = "" ;
        HttpResponse response;
try { String url = String.format(URL_SESSION, email); HttpGet request = new HttpGet(url); <b>response = client.execute(request);</b> } catch (Throwable e) { LOG.error("Could not reach to the Server"); throw new ExecutionException(e, "Could not reach to the Server") .withReason(Throwables.getRootCause(e).getMessage()) .withResolution("Check if the outbound Port is open and you can reach the Rapportive service"); }

在我的单元测试中,我想注入HttpClient以获得模拟响应。我写了一个Mock Class

public abstract class MockHttpRequestBadQuery implements HttpClient {

    protected HttpResponse execute(HttpGet httpUriRequest) throws IOException {
        HttpResponse httpResponse = new BasicHttpResponse(new StatusLine() {
            @Override
            public ProtocolVersion getProtocolVersion() {
                return new ProtocolVersion("HTTP/1.1", 0, 0);
            }

            @Override
            public int getStatusCode() {
                return 400;
            }

            @Override
            public String getReasonPhrase() {
                return "Bad Request";
            }
        });
        HttpEntity entity = new StringEntity("{\"message\":\"\\n" +
                "SELECT badFieldName FROM Account\\n" +
                "       ^\\n" +
                "ERROR at Row:1:Column:8\\n" +
                "No such column \'badFieldName\' on entity \'Account\'. If you are attempting to use" +
                " a custom field, be sure to append the \'__c\' after the custom field name. Please" +
                " reference your WSDL or the describe call for the appropriate names.\"," +
                " \"errorCode\":\"INVALID_FIELD\"}");
        httpResponse.setEntity(entity);
        httpResponse.setHeader("Content-Type", "application/json;charset=UTF-8");
        httpResponse.setHeader("Date", "Tue, 28 May 2013 16:06:21 GMT");
        httpResponse.setHeader("Transfer-Encoding", "chunked");
        return httpResponse;
    }
}

我需要有关如何注入的帮助,以便每当调用client.execute()时,都会生成模拟响应。

1 个答案:

答案 0 :(得分:2)

从您发布的代码中不清楚如何将真实HttpClient依赖项添加到真实类中。但是,您可以通过以下方式为实际和测试场景执行此操作:

public class RealClassThatNeedsClientDep {

    @Inject private HttpClient client;

    public method useClient() {
        client.doStuff(); // client was injected at instance creation by Guice
    }

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new RealModule());
        injector.getInstance(RealClassThatNeedsClientDep.class).useClient();
    }
}

该类将客户端作为注入的实例变量。如果该客户端类有一个默认的no-args构造函数,那么这就是你需要做的。如果没有,或者如果要将自定义逻辑应用于正在注入的客户端,那么在RealModule中,您可以使用提供程序绑定客户端。注意我不知道你使用的HttpClient是什么类型,所以下面的方法很可能都是假的。

public class RealModule {
    /** provider only needed if HttpClient has no default no-args public constructor */
    @Provides HttpClient getClient() {
        return HttpClient.getNewInstance().customize();
    }
}

在测试模块中,您可以绑定模拟客户端进行注入,并将测试模块安装到测试类中。

public class TestModule {

    @Provides HttpClient getClient() {
        // define mock client using Mockito or roll your own
    }
}