Come unittest una classe utilizzando RestTemplate offline?
-
09-10-2019 - |
Domanda
Ho una classe che ha la dipendenza diretta sul RestTemplate. Mi piacerebbe avere un test JUnit di esso, non in linea.
Come potrei prendere in giro un RestTemplate nel mio unittest?
Soluzione
Suggerisco di refactoring del codice del client per Rimuovi la dipendenza diretta su RestTemplate
, e sostituirlo con riferimenti a RestOperations
, che è l'interfaccia implementata da RestTemplate
. e quello che dovrebbe essere di codifica.
È quindi possibile iniettare uno stub o finto di RestOperations
nel codice per unit testing, e iniettare un RestTemplate
quando si utilizza per davvero.
Altri suggerimenti
Sping 3.0 ha introdotto RestTemplate
. A partire dalla versione 3.2, il Primavera framework di test MVC ha fornito la classe MockRestServiceServer
per unità di testare codice client REST.
È possibile utilizzare le classi Mock nel pacchetto org.springframework.mock.web
.
Di solito si avrà bisogno di MockHttpServletRequest
e MockHttpServletResponse
, ma se avete bisogno di un maggiore controllo potrebbe anche essere necessario, ad esempio, gli altri MockRequestDispatcher
.
Entrambi questi attuare le corrispondenti interfacce Servlet ma aggiungere metodi di convenienza per testare (e, cosa più importante: lavorano senza una connessione HTTP reale).
Si possono trovare le classi Mock nel vaso primavera-test ( accessibili attraverso Maven )
Aggiornamento: sembra che le classi di cui sopra non sono di grande aiuto per RestTemplate
dopo tutto. Che cosa hai bisogno è quello di creare un mock ClientHttpRequestFactory
, e sono sorpreso di vedere che non ce n'è uno nel pacchetto di cui sopra. Ecco il codice per iniziare (non hanno provato):
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();
}
}
}
primavera-sociale-test contiene classi mockup che i test di aiuto scrittura per RestTemplate
. Ci sono anche alcuni esempi su come utilizzare all'interno del repository Git (ad esempio, OAuth1TemplateTest ).
Si prega di tenere presente che c'è attualmente una richiesta di funzionalità Primavera ( # SPR-7951 ) per spostare queste classi per la primavera-web.