30

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

我怎么能在我的单元测试中模拟一个 RestTemplate?

4

4 回答 4

35

Sping 3.0 推出RestTemplate。从 3.2 版本开始,Spring MVC 测试框架提供了MockRestServiceServer用于单元测试客户端 REST 代码的类。

于 2013-09-12T09:50:00.730 回答
31

我建议重构您的客户端代码以删除对 的直接依赖RestTemplate,并将其替换为对 的引用RestOperations,这是由RestTemplate. 和你应该编码的那个。

然后,您可以将 stub 或 mock 注入RestOperations到您的代码中以进行单元测试,并RestTemplate在实际使用时注入 a。

于 2011-01-10T10:48:32.787 回答
5

您可以在 package 中使用 Mock 类org.springframework.mock.web

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

它们都实现了相应的 Servlet 接口,但添加了方便的测试方法(最重要的是:它们无需真正的 HTTP 连接即可工作)。

您可以在 spring-test jar 中找到 Mock 类(可通过 Maven 访问


更新:似乎上述课程RestTemplate毕竟没有太大帮助。您需要创建一个 mock 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();
        }

    }


}
于 2011-01-10T08:40:37.553 回答
3

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

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

于 2011-04-20T09:16:33.657 回答