Cómo unittest una clase usando RestTemplate fuera de línea?
-
09-10-2019 - |
Pregunta
Tengo una clase que tiene dependencia directa de la RestTemplate. Me gustaría tener una prueba unitaria de él, fuera de línea.
¿Cómo podría burlarse de un RestTemplate en mi unittest?
Solución
Sugiero refactorización su código de cliente a Eliminar la dependencia directa de RestTemplate
, y reemplazarlo con referencias a RestOperations
, que es la interfaz implementada por RestTemplate
. y el que se debe a la codificación.
A continuación, puede inyectar un talón o simulacro de RestOperations
en su código para las pruebas unitarias, e inyectar un RestTemplate
cuando se la usa de verdad.
Otros consejos
Sping 3.0 introdujo RestTemplate
. Desde la versión 3.2, el primavera marco de pruebas MVC ha proporcionado la clase MockRestServiceServer
para la unidad de probar código RESTO cliente.
You can use the Mock classes in package org.springframework.mock.web
.
Usually you will need MockHttpServletRequest
and MockHttpServletResponse
, but if you need more control you may also need others, e.g. MockRequestDispatcher
.
Both of these implement the corresponding Servlet interfaces but add convenience methods for testing (and, most importantly: they work without a real HTTP connection).
You can find the Mock classes in the spring-test jar (accessible through Maven)
Update: it seems that the above classes are no great help for RestTemplate
after all. What you will need is to create a mock ClientHttpRequestFactory
, and I'm surprised to see that there isn't one in the above package. Here is some code to get you started (haven't tested it):
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 contains mockup classes that help write tests for RestTemplate
. There are also some examples on how to use it within the git repository (e.g. OAuth1TemplateTest).
Please keep in mind that there's currently a Spring feature request (#SPR-7951) to move these classes to spring-web.