Как протестировать класс с помощью RestTemplate в автономном режиме? - PullRequest
30 голосов
/ 10 января 2011

У меня есть класс, который напрямую зависит от RestTemplate.Я хотел бы, чтобы у меня был тест JUnit, в автономном режиме.

Как я могу смоделировать RestTemplate в моем unittest?

Ответы [ 4 ]

35 голосов
/ 12 сентября 2013

Представлен Sping 3.0 RestTemplate. Начиная с версии 3.2, среда тестирования Spring MVC предоставляет класс MockRestServiceServer для модульного тестирования клиентского кода REST.

31 голосов
/ 10 января 2011

Я предлагаю изменить код вашего клиента на удалить прямую зависимость от RestTemplate и заменить ее ссылками на RestOperations, который является интерфейсом, реализованным RestTemplate.и тот, который вы должны кодировать.

Затем вы можете добавить заглушку или макет RestOperations в ваш код для модульного тестирования и добавить RestTemplate при его реальном использовании.

5 голосов
/ 10 января 2011

Вы можете использовать классы Mock в пакете org.springframework.mock.web.

Обычно вам понадобятся MockHttpServletRequest и MockHttpServletResponse, но если вам нужно больше контроля, вам могут понадобиться и другие, например, MockRequestDispatcher.

Оба они реализуют соответствующие интерфейсы Servlet, но добавляют удобные методы для тестирования (и, самое главное:они работают без реального соединения HTTP).

Вы можете найти классы Mock в банке для весеннего тестирования (, доступной через Maven )


Обновление: кажется, что перечисленные выше классы не очень помогают для 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 голосов
/ 20 апреля 2011

spring-social-test содержит классы макетов, которые помогают писать тесты для RestTemplate. Есть также несколько примеров того, как использовать его в репозитории git (например, OAuth1TemplateTest ).

Имейте в виду, что в настоящее время существует запрос функции Spring ( # SPR-7951 ) для перемещения этих классов в spring-web.

...