2009-03-03 9 views

risposta

11

Provare (Maven) è molto facile da incorporare in un test di unità. Prendi RoundTripTest ed esempi come PostTest scritto con Simple. Fornisce un esempio di come incorporare il server nel tuo caso di test.

Anche Simple è molto più leggero e veloce di Jetty, senza dipendenze. Quindi non dovrai aggiungere diversi jar al tuo classpath. Né dovrai preoccuparti di WEB-INF/web.xml o di altri artefatti.

+2

Anche se probabilmente è ciò che l'utente desiderava, questo non è un server Web "fittizio", è un vero server web che viene lanciato all'interno del test dell'unità.Ad esempio, se la porta è stata presa, fallirebbe, quindi non un vero finto (cioè ha una dipendenza esterna dal sistema). Secondo la nomenclatura di Martin Fowler fore ["Test Doubles"] (http://www.martinfowler.com/bliki/TestDouble.html), questo è un "falso". Detto questo, era ** esattamente ** quello che stavo cercando. – ArtB

+0

Questo progetto è andato a finire? – kbolino

18

Si sta tentando di utilizzare un server Web mock or an embedded?

Per un web server finta, provare a utilizzare Mockito, o qualcosa di simile, e solo deridere il HttpServletRequest e HttpServletResponse oggetti come:

MyServlet servlet = new MyServlet(); 
HttpServletRequest mockRequest = mock(HttpServletRequest.class); 
HttpServletResponse mockResponse = mock(HttpServletResponse.class); 

StringWriter out = new StringWriter(); 
PrintWriter printOut = new PrintWriter(out); 
when(mockResponse.getWriter()).thenReturn(printOut); 

servlet.doGet(mockRequest, mockResponse); 

verify(mockResponse).setStatus(200); 
assertEquals("my content", out.toString()); 

Per un server web incorporato, è possibile utilizzare Jetty, che puoi use in tests.

6

Un'altra buona alternativa potrebbe essere MockServer; fornisce un'interfaccia fluente con la quale è possibile definire il comportamento del server Web deriso.

+0

Anche il MockServer dipende da Netty (non da Jetty). –

19

Wire Mock sembra offrire un solido insieme di matrici e mock per testare servizi web esterni.

@Rule 
public WireMockRule wireMockRule = new WireMockRule(8089); 


@Test 
public void exactUrlOnly() { 
    stubFor(get(urlEqualTo("/some/thing")) 
      .willReturn(aResponse() 
       .withHeader("Content-Type", "text/plain") 
       .withBody("Hello world!"))); 

    assertThat(testClient.get("/some/thing").statusCode(), is(200)); 
    assertThat(testClient.get("/some/thing/else").statusCode(), is(404)); 
} 

Può essere integrato anche con Spock. Esempio trovato here.

+0

Questo ha funzionato molto bene per me. L'uso di wireMockConfig(). DynamicPort() rende più prevedibile un'impostazione in cui altri programmi potrebbero utilizzare la porta. Vorrei che fosse l'impostazione predefinita in quanto mi mancava quasi questa possibilità e ho saltato questa fantastica libreria. – morten

+0

Che cos'è testClient nel codice che hai fornito? – gribo

+0

@gribo Suppongo che testClient sia la tua istanza attuale sotto test. – Stephan

5

Puoi provare Jadler (http://jadler.net) che è una libreria con un'API Java programmatica fluida per bloccare e simulare le risorse http nei test. Esempio:

onRequest() 
    .havingMethodEqualTo("GET") 
    .havingPathEqualTo("/accounts/1") 
    .havingBody(isEmptyOrNullString()) 
    .havingHeaderEqualTo("Accept", "application/json") 
.respond() 
    .withDelay(2, SECONDS) 
    .withStatus(200) 
    .withBody("{\\"account\\":{\\"id\\" : 1}}") 
    .withEncoding(Charset.forName("UTF-8")) 
    .withContentType("application/json; charset=UTF-8"); 
+0

Ho provato ad usare Jadler ma ogni volta che provo a chiamare 'initJadler()' sto ricevendo l'errore come menzionato https://github.com/jadler-mocking/jadler/issues/107. Qualche idea di cosa potrebbe andare storto? – tuk

+0

Potresti incollare un risultato della dipendenza da mvn: albero qui? Potrebbe essere uno scontro di librerie. –

+1

Si prega di leggere la mia risposta in github.com/jadler-mocking/jadler/issues/107, il problema è causato dal conflitto di versioni di Jetty (8 vs 9). Puoi rimuovere la dipendenza di Jetty9 (se non è necessaria per l'esecuzione di test) o eseguire Jadler senza la dipendenza da Jetty (https://github.com/jadler-mocking/jadler/wiki/Using-the-Alternative-Stub-Server -Implementazione) –

4

è possibile scrivere un mock con classe del JDK HttpServer così (senza dipendenze esterne richiesti). Vedi this blog post che spiega come.

In sintesi:

HttpServer httpServer = HttpServer.create(new InetSocketAddress(8000), 0); 
httpServer.createContext("/api/endpoint", new HttpHandler() { 
    public void handle(HttpExchange exchange) throws IOException { 
     byte[] response = "{\"success\": true}".getBytes(); 
     exchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, response.length); 
     exchange.getResponseBody().write(response); 
     exchange.close(); 
    } 
}); 
httpServer.start(); 

try { 
// Do your work... 
} finally { 
    httpServer.stop(0); 
} 
+0

C'è un modo per affermare se il 'HttpServer' ha ricevuto una richiesta? –

1

Se si utilizza Apache HttpClient, questa sarà una buona alternativa. HttpClientMock

HttpClientMock httpClientMock = new httpClientMock() 
HttpClientMock("http://example.com:8080"); 
httpClientMock.onGet("/login?user=john").doReturnJSON("{permission:1}"); 

Full Disclosure: Io sono l'autore della biblioteca.

Problemi correlati