2011-01-10 6 views
30

У меня есть класс, который имеет прямую зависимость от RestTemplate. Мне жаль, что у меня нет теста JUnit, в автономном режиме.Как отключить класс с помощью RestTemplate в автономном режиме?

Как я мог издеваться над RestTemplate в моем unittest?

+0

Посмотрите мой ответ здесь http://stackoverflow.com/a/22334918/1077708 – vincentjames501

ответ

31

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

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

+0

Что сказал мистер @skaffman, как правило, верно и правильно.Тем не менее, я должен указать, что 'RestTemplate' используется в значительной степени. В любом случае google возьмет вас, даже« MockRestServiceServer »(как указал @Raedwald). Кроме того, Javadoc для состояния «RestOperations» _Не часто используется напрямую, но является полезным вариантом для повышения тестовой способности, поскольку его можно легко обмануть или заколоть. _ – demaniak

+0

Следующий вопрос: если вы используете 'RestOperations', а экземпляр - потребляемый реализацией 'Service' (тестируемый класс), как бы вы могли получить издевательский экземпляр' RestOperations' в службу? Мгновентировать службу непосредственно в тесте и использовать сеттер? – demaniak

+1

В наши дни очень легко издеваться над «RestTemplate», но довольно сложно реализовать все методы «RestOperations». –

5

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

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

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

Вы можете найти Mock классов в весенне-тесте баночке (accessible through Maven)


Update:, кажется, что вышеуказанные классы не являются большим подспорьем для 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(); 
     } 

    } 


} 
+1

Вы не ответили на мой вопрос. Ваше решение помогает справиться с сервлетом на стороне сервера, средой MVC. Я собираюсь протестировать клиентскую сторону, использующую среду MVC. –

+0

@ Dennis okay, я обновил свой ответ –

+1

Это именно то, что я сделал для одного из моих проектов REST. Огромное спасибо. – Elwood

3

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

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

+0

Это *** очень полезно для тестирования клиентов отдыха. –

+1

они переместили это в [spring-test-mvc] (http://tinyurl.com/csmuvdz) – mfirry

35

Sping 3,0 введено RestTemplate. Начиная с версии 3.2, Spring MVC test framework предоставил класс MockRestServiceServer для идентификационного кода клиента REST.

+0

Доступно ли это на Android? – Piotr

+1

@Piotr, Это работает для меня с градиентом: androidTestCompile ("org.springframework: spring-test: 3.2.8.RELEASE") { исключить модуль: "spring-core" } – vincentjames501