2011-01-10 16 views

Respuesta

31

Sugiero refactorización su código de cliente para eliminar la dependencia directa de RestTemplate, y reemplazarlo con referencias a RestOperations, que es el interfaz implementada por RestTemplate. y el que deberías codificar.

A continuación, puede inyectar un stub o simulacro de RestOperations en su código para probar la unidad e inyectar un RestTemplate cuando lo utilice de manera real.

+0

Lo que el Sr. @skaffman dijo es generalmente cierto y correcto.Sin embargo, debo señalar que 'RestTemplate' se usa prácticamente en TODAS PARTES, google lo llevará, incluso' MockRestServiceServer' (como señala @Raedwald). Además, Javadoc para el estado 'RestOperations' _No se usa a menudo directamente, pero es una opción útil para mejorar la capacidad de prueba, ya que se puede burlar o repicar fácilmente._ – demaniak

+0

Una pregunta de seguimiento: si usa' RestOperations', y la instancia es consumido por una implementación de 'Servicio' (clase bajo prueba), ¿cómo conseguirías la instancia de 'RestOperations' burlada en el servicio? Crear una instancia del servicio directamente en la prueba, y usar un setter? – demaniak

+1

Es muy fácil simular una 'RestTemplate' en estos días, pero es bastante difícil implementar todos los métodos de' RestOperations'. –

5

Puede usar las clases de Mock en el paquete org.springframework.mock.web.

Normalmente necesitará MockHttpServletRequest y MockHttpServletResponse, pero si necesita más control, es posible que también necesite otras, p. MockRequestDispatcher.

Ambos implementan las interfaces de servlets correspondientes pero agregan métodos de conveniencia para probar (y, lo más importante: funcionan sin una conexión HTTP real).

Usted puede encontrar las clases Mock en el frasco-pruebas de la primavera (accessible through Maven)


Actualización: parece que las clases anteriores no son una gran ayuda para RestTemplate después de todo. Lo que necesitará es crear un simulacro ClientHttpRequestFactory, y me sorprende ver que no hay ninguno en el paquete anterior. Aquí hay un código para que pueda empezar (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(); 
     } 

    } 


} 
+1

No respondiste mi pregunta. Su solución ayuda en la prueba del servlet del lado del servidor, MVC framework. Voy a probar el lado del cliente, que usa el framework MVC. –

+0

@Dennis bien, actualicé mi respuesta –

+1

Esto es justo lo que buscaba para uno de mis proyectos REST. Muchas gracias. – Elwood

3

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 primavera (#SPR-7951) para mover estas clases a spring-web.

+0

Esto es *** muy *** útil para probar clientes en reposo. –

+1

movieron esto a [spring-test-mvc] (http://tinyurl.com/csmuvdz) – mfirry

35

Sping 3.0 introducido RestTemplate. Desde la versión 3.2, el Spring MVC test framework ha proporcionado la clase MockRestServiceServer para probar el código REST del cliente.

+0

¿Está disponible en Android? – Piotr

+1

@Piotr, esto funciona para mí con gradle: androidTestCompile ("org.springframework: spring-test: 3.2.8.RELEASE") { excluye el módulo: "spring-core" } – vincentjames501

Cuestiones relacionadas