java - test - ¿Cómo probar una clase usando RestTemplate sin conexión?
resttemplate test (4)
Tengo una clase que tiene dependencia directa en RestTemplate. Me gustaría tener una prueba de JUnit, sin conexión.
¿Cómo podría simular una RestTemplate en mi prueba unitaria?
Puede usar las clases de Mock en el paquete org.springframework.mock.web
.
Por lo general, necesitará MockHttpServletRequest
y MockHttpServletResponse
, pero si necesita más control, es posible que también necesite otros, por ejemplo, MockRequestDispatcher
.
Ambos implementan las interfaces de Servlet correspondientes, pero agregan métodos de conveniencia para las pruebas (y, lo más importante: funcionan sin una conexión HTTP real).
Puede encontrar las clases de Mock en el contenedor de prueba de primavera ( accesible a través de Maven )
Actualización: parece que las clases anteriores no son de gran ayuda para RestTemplate
después de todo. Lo que necesitará es crear un ClientHttpRequestFactory
falso, y me sorprende ver que no hay uno en el paquete anterior. Aquí hay un código para comenzar (no lo he probado):
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();
}
}
}
Sugiero refactorizar su código de cliente para eliminar la dependencia directa de RestTemplate
, y reemplazarlo con referencias a RestOperations
, que es la interfaz implementada por RestTemplate
. y el que deberías codificar.
Luego puede inyectar un stub o simulacro de RestOperations
en su código para pruebas unitarias, e inyectar un RestTemplate
cuando lo use de manera real.
spring-social-test contiene clases de maquetas que ayudan a escribir pruebas para RestTemplate
. También hay algunos ejemplos sobre cómo usarlo dentro del repositorio de git (por ejemplo, OAuth1TemplateTest ).
Tenga en cuenta que actualmente hay una solicitud de función de Spring ( # SPR-7951 ) para mover estas clases a spring-web.
Sping 3.0 introdujo RestTemplate
. Desde la versión 3.2, el marco de prueba Spring MVC ha proporcionado la clase MockRestServiceServer
para la prueba unitaria del código REST del cliente.