2015-05-14 18 views
6

Sto creando test unitari in un'applicazione Java Spring Boot per una classe di servizio.Test unitario con jUnit e Mockito per chiamate API REST esterne

La classe di servizio effettua una chiamata esterna a un servizio API REST che restituisce una risposta JSON. Sto prendendo in giro questa chiamata usando Mockito. Sto codificando un JSON nella risposta mockserver.

È questa cattiva pratica avere JSON hardcoded nei test di unità? Se la struttura JSON cambia, il test dovrebbe fallire è il mio ragionamento. C'è una migliore, migliore pratica dove farlo?

frammento di esempio di seguito:

Il codice attuale è funzionale, ho appena modificato questo frammento per brevità per ottenere l'idea attraverso, in modo da inviare un commento se vedi eventuali errori:

public class UserServiceTest extends TestCase { 

    private static final String MOCK_URL = "baseUrl"; 
    private static final String DEFAULT_USER_ID = "353"; 

    UserService classUnderTest; 
    ResponseEntity<Customer> mockResponseEntity; 
    MockRestServiceServer mockServer; 
    @Mock 
    RestTemplate mockRestTemplate; 

    public void setUp() throws Exception { 
     super.setUp(); 

     classUnderTest = new UserRestService(); 
     mockRestTemplate = new RestTemplate(); 
     mockServer = MockRestServiceServer.createServer(mockRestTemplate); 

     ReflectionTestUtils.setField(classUnderTest, "restTemplate", 
       mockRestTemplate); 
     ReflectionTestUtils.setField(classUnderTest, "userSvcUrl", 
       MOCK_URL); 
    } 

    public void testGetUserById() throws Exception { 

     mockServer.expect(requestTo(MOCK_URL + "/Users/" + DEFAULT_USER_ID)).andExpect(method(HttpMethod.GET)) 
       .andRespond(withSuccess(
         "{\n" + 
           " \"UserCredentials\": {\n" + 
           "  \"Password\": \"\",\n" + 
           "  \"PasswordNeedsUpdate\": false,\n" + 
           "  \"Security\": [\n" + 
           "   {\n" + 
           "    \"Answer\": \"\",\n" + 
           "    \"Question\": \"Why did the bicycle fall over?\"\n" + 
           "   }\n" + 
           "  ]\n" + 
           "}" 
         , MediaType.APPLICATION_JSON)); 


     Customer customer = classUnderTest.getUserById(DEFAULT_USER_ID); 

     mockServer.verify(); 
     assertNotNull(customer); 
     assertEquals(DEFAULT_USER_ID, customer.getId()); 
    } 
} 
+0

JUnit indica che il metodo di installazione deve essere statico. Dove è definito il metodo withSuccess()? – chrisinmtown

risposta

7

Attualmente sono nella stessa barca come te e il mio ragionamento era il seguente: Creare una risposta JSON fittizia è come prendere in giro un oggetto e controllarlo usando Mockito.when. Dovresti modificare qualcosa nella chiamata when().thenReturn() quando hai modificato alcune analisi interne o ti aspettavi risultati diversi. Questo è lo stesso con una risposta JSON in cui le chiamate vengono cambiate e le rappresentazioni degli oggetti vengono alterate.

Quindi la mia ipotesi sarebbe che questo va bene. Leggendo vari articoli su come testare le API REST, il consenso generale è che la creazione di risposte JSON fittizie è una buona pratica. La migliore pratica sarebbe (di volta in volta) scaricare la vera risposta JSON e inserirla come risposta derisoria. In questo modo è possibile mantenere i test aggiornati con la parte esterna, mentre i test possono essere eseguiti senza richieste Internet.

Edit come richiesto:

+0

Hey Tim ti dispiacerebbe modificare il tuo post con alcune delle fonti che hai usato solo come riferimento? – anataliocs

+0

Ciao Anataliocs, ho aggiunto alcuni dei riferimenti che ho trovato. Spero che ti aiutano =] –

+1

Fantastico, grazie mille. Questo mi dà molta più fiducia nel mio approccio, dal momento che i cattivi test unitari sono quasi peggiori di quelli che non dicono: – anataliocs

4

Vorrei evidenziare un altro approccio da considerare, e cioè creare POJO (ad es. modello di dati, JavBean) dell'oggetto che il JSON rappresenta quindi utilizzando un serializzatore JSON, come Gson di Google, per convertirlo in una stringa JSON.

UserCredentials uc = new UserCredentials(); 
//set the values 
Gson gson = new GsonBuilder().setPrettyPrinting().create(); 
String json = gson.toJson(uc); 
+0

Non ci avevo nemmeno pensato. Mi piace molto questo approccio. Grazie per l'input. – anataliocs