如何使用RestTemplate脱机进行单元测试?

时间:2011-01-10 01:51:51

标签: java unit-testing spring junit resttemplate

我有一个直接依赖于RestTemplate的类。我希望我有离线的JUnit测试。

我如何在我的unittest中模拟RestTemplate?

4 个答案:

答案 0 :(得分:35)

Sping 3.0引入了RestTemplate。从版本3.2开始,Spring MVC test framework为单元测试客户端REST代码提供了类MockRestServiceServer

答案 1 :(得分:31)

我建议重构您的客户端代码,以删除RestTemplate的直接依赖,并将其替换为RestOperations的引用,RestTemplateRestOperations实现的接口}。以及你应该编写的那个。

然后,您可以将RestTemplate的存根或模拟注入到代码中进行单元测试,并在将其用于实际时注入{{1}}。

答案 2 :(得分:5)

您可以使用包org.springframework.mock.web中的模拟类。

通常您需要MockHttpServletRequestMockHttpServletResponse,但如果您需要更多控制权,您可能还需要其他人,例如MockRequestDispatcher

这两个实现了相应的Servlet接口,但为测试添加了便利方法(最重要的是:它们在没有真正的HTTP连接的情况下工作)。

你可以在spring-test jar(accessible through Maven

中找到Mock类

更新:毕竟上述类似乎对RestTemplate没什么帮助。你需要的是创建一个模拟ClientHttpRequestFactory,我很惊讶地看到上面的包中没有一个。这里有一些代码可以帮助您入门(尚未测试过):

public class MockClientHttpRequestFactory implements
    ClientHttpRequestFactory{

    // overwrite this if you want
    protected MockClientHttpResponse createResponse(){
        return new MockClientHttpResponse();
    }

    // or this
    protected HttpStatus getHttpStatusCode(){
        return HttpStatus.OK;
    }

    // or even this
    @Override
    public ClientHttpRequest createRequest(final URI uri,
        final HttpMethod httpMethod) throws IOException{
        return new MockClientHttpRequest(uri, httpMethod);
    }

    public class MockClientHttpResponse implements ClientHttpResponse{
        private final byte[] data = new byte[10000];
        private final InputStream body = new ByteArrayInputStream(data);
        private final HttpHeaders headers = new HttpHeaders();
        private HttpStatus status;

        @Override
        public InputStream getBody() throws IOException{
            return body;
        }

        @Override
        public HttpHeaders getHeaders(){
            return headers;
        }

        @Override
        public HttpStatus getStatusCode() throws IOException{
            return getHttpStatusCode();
        }

        @Override
        public String getStatusText() throws IOException{
            return status.name();
        }

        @Override
        public void close(){
            try{
                body.close();
            } catch(final IOException e){
                throw new IllegalStateException(e);
            }

        }

    }

    class MockClientHttpRequest implements ClientHttpRequest{

        private final HttpHeaders headers = new HttpHeaders();
        private final HttpMethod method;
        private final URI uri;
        private final OutputStream body = new ByteArrayOutputStream();

        MockClientHttpRequest(final URI uri, final HttpMethod httpMethod){
            this.uri = uri;
            method = httpMethod;

        }

        @Override
        public OutputStream getBody() throws IOException{
            return body;
        }

        @Override
        public HttpHeaders getHeaders(){
            return headers;
        }

        @Override
        public HttpMethod getMethod(){
            return method;
        }

        @Override
        public URI getURI(){
            return uri;
        }

        @Override
        public ClientHttpResponse execute() throws IOException{
            return createResponse();
        }

    }


}

答案 3 :(得分:3)

spring-social-test包含帮助编写RestTemplate测试的模型类。还有一些关于如何在git存储库中使用它的例子(例如OAuth1TemplateTest)。

请记住,目前有一个Spring功能请求(#SPR-7951)将这些类移到spring-web。