Как объединить класс с помощью RestTemplate в автономном режиме?
У меня есть класс, который имеет прямую зависимость от RestTemplate. Я бы хотел, чтобы у меня был тест JUnit, в автономном режиме.
Как я могу издеваться над RestTemplate в мой unittest?
4 ответа:
Я предлагаю рефакторинг вашего клиентского кода дляудалить прямую зависимость от
RestTemplate
и заменить ее ссылками наRestOperations
, который является интерфейсом, реализованнымRestTemplate
. и тот, на который ты должен писать код.Затем вы можете ввести заглушку или макет
RestOperations
в свой код для модульного тестирования и ввестиRestTemplate
при его реальном использовании.
Sping 3.0 ввел
RestTemplate
. Начиная с версии 3.2, Spring MVC test framework предоставляет классMockRestServiceServer
для модульного тестирования клиентского кода REST.
Вы можете использовать фиктивные классы в пакете
org.springframework.mock.web
.Обычно вам понадобится
MockHttpServletRequest
и ещеMockHttpServletResponse
, но если вам нужно больше контроля, вам могут понадобиться и другие, напримерMockRequestDispatcher
.Оба они реализуют соответствующие интерфейсы сервлетов, но добавляют удобные методы тестирования (и, самое главное: они работают без реального HTTP-соединения).
Вы можете найти фиктивные классы в банке весеннего теста (, доступном через 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(); } } }
Spring-social-test содержит классы макетов, которые помогают писать тесты для
RestTemplate
. Есть также несколько примеров того, как использовать его в репозитории git (например, OAuth1TemplateTest).Пожалуйста, имейте в виду, что в настоящее время есть запрос функции Spring (#SPR-7951) для перемещения этих классов в spring-web.