2013-12-13 18 views
6

Ho un contuso oggetto JSON, ma hanno bisogno di prendere in giro il seguente utilizzando Mockito:Utilizzando Mockito for Client HTTP

HttpResponse response = defaultHttpClient.execute(postRequest); 
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
StringBuilder result = new StringBuilder(); 
while ((line = rd.readLine()) != null) { 
    result.append(line);   
} 
JSONObject jsonResponseObject = new JSONObject(result.toString()); 

ho creato il seguente Mocks:

@Mock 
    private HttpClient mockHttpClient; 
    private HttpPost mockHttpPost; 
    private HttpResponse mockHttpResponse; 
    private HttpEntity mockHttpEntity; 
    private InputStream mockInputStream; 
    private InputStreamReader mockInputStreamReader; 
    private BufferedReader mockBufferedReader; 

e hanno le seguenti when dichiarazioni :

Mockito.when(mockHttpClient.execute(mockHttpPost)).thenReturn(mockHttpResponse); 
    Mockito.when(mockHttpResponse.getEntity()).thenReturn(mockHttpEntity); 
    Mockito.when(mockHttpEntity.getContent()).thenReturn(mockInputStream); 

Domanda: Devo creare tutte queste statistiche "quando" ents e se sì allora quali altri devo creare per essere in grado di arrivare al JSON stoppato?

Qualche suggerimento pls?

Grazie

+0

Si prega di aggiungere un po 'di codice in modo da poter capire gli oggetti di simulazione esatti –

+0

Stai usando qualsiasi framework web come Spring MVC? – SergeyB

risposta

1

Sì, potrebbe essere necessario tutte le dichiarazioni che quando hai citato. Ma invece di restituire il mockInputStream, si può solo tornare new ByteArrayInputStream("{foo : 'bar'}".getBytes())

Infine, si potrebbe verificare che l'oggetto risposta JSON ha una proprietà 'foo' che ha un valore di 'bar'.

Detto questo, non sono sicuro che valga la pena testare il metodo dato, poiché tutto fa aprire flussi e leggere dati.

0

Prima comprensione del significato di Mocking.

1) Perché abbiamo bisogno di deridere?

Supponiamo di non voler chiamare alcun metodo originale e vogliamo che invece di quel metodo originale dovremmo chiamare un metodo fittizio, allora dovremmo andare a prendere in giro.

Per es:

Mockito.when(mockHttpClient.execute(mockHttpPost)).thenReturn(mockHttpResponse) 

Ciò significa ogni volta che questo execute() saranno chiamati allora si avrà restituire il proprio valore preparato invece di originale mockHttpResponse.

Quindi nel tuo caso prepara il tuo oggetto stub e mockit se ne hai bisogno. Qui si prepara la risposta (nota attuale ma fittizia).

mockHttpResponse.setEntity(new Entity()); 
mockHttpResponse.getEntity().setContent('{yourJsonString}'); 

Così ogni volta che il vostro

mockHttpClient.execute(mockHttpPost); //will be called 

Poi tornerà la risposta che avete preparato nel vostro metodo di prova manualmente.

Quando il controllo viene a

new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 

Poi si aprirà {yourJsonString} quando response.getEntity().getContent() si chiama e lasciare che il codice resto fare la sua funzionalità. Alla fine il tuo oggetto JSON stub sarà preparato.

Ricorda che i casi di test sono solo di aiuto per gli sviluppatori. Possiamo prendere in giro qualsiasi cosa e restituire qualsiasi oggetto stub. Basta scrivere un caso di test per controllare il flusso di controllo passando i valori previsti e non previsti.

Questo renderà il vostro lavoro semplice. Ora volete prendere in giro la vostra classe BufferReader usarlo.

BufferedReader bufferedReader = org.mockito.Mockito.mock(BufferedReader.class); 
when(bufferedReader.readLine()).thenReturn("first line").thenReturn("second line"); 

org.junit.Assert.when(new Client(bufferedReader).parseLine()).thenEquals(IsEqual.equalTo("1")); 
+0

Ciao Shoaib, grazie per il chiarimento !! Non sono sicuro di cosa si debba fare qui, ma sto cercando di evitare di effettuare una chiamata HttpClient effettiva poiché ho la versione finale elaborata (Parsed) della risposta da questa chiamata, che è un oggetto JSON che ho stubato. Si prega di avvisare .. Grazie –

+0

Si prega di controllare il codice aggiornato –

+0

Questo è molto utile. Ma come ho detto sopra nella mia domanda, restituisco un mockHttpResponse quando HttpResponse response = defaultHttpClient.execute (postRequest) viene chiamato. Ma poi nel metodo attuale, devo eseguire 3 passaggi prima che venga restituito l'oggetto JSON. Quindi, se dovessi restituire l'oggetto JSON stoppato quando viene eseguito response.getEntity(). GetContent(), non sarà un problema quando vengono eseguite istruzioni successive nel mio metodo originale? Si prega di avvisare .. –

6

Si potrebbe avere per deridere HttpClient e HttpResponse, se sono le interfacce (anche se, a seconda della vostra biblioteca, è possibile utilizzare MockHttpClient o MockHttpResponse), ma non si dovrebbe essere beffardo qualsiasi altra cosa .

Perché?

Il mock sta stabilendo un comportamento di output previsto su classi che non possiamo rendere concrete, o meglio, classi che vogliamo comportarci in un certo modo per questa particolare istanza di un test. Si desidera assicurarsi di ottenere la risposta corretta da un simulato HttpClient e che quando viene chiamato response.getEntity(), restituisca un valore significativo HttpEntity. Puoi scegliere di deriderlo o meno; Personalmente non lo farei, in quanto il mock non aggiunge alcun valore aggiuntivo (eccetto forse per verificare che sia stato chiamato un metodo particolare).

Tutto il resto è un'implementazione concreta: è necessario consentire agli altri oggetti di interagire con i risultati degli elementi precedentemente simulati per garantire che si comportino come farebbero se non ci fossero mock.

In realtà ... non puoi davvero deridere quelli a meno che non li passi o li inietti in qualche modo. Vorrei fortemente scoraggiarti dal tentativo di prendere in giro qualsiasi oggetto new in quel metodo.

Non si specifica cosa si sta asserendo, ma mi aspetto che sia il tuo JSONObject in qualche capacità. Direi che quello che ci si aspettava fosse inserito in realtà lo ha fatto nell'oggetto JSON, e anche verificare che i tuoi oggetti derisi siano stati chiamati e invocati nel modo in cui ti aspettavi che fossero.

tuo annotazione @Mock non è cascata, tra l'altro - si deve annotare tutti i campi deriso con @Mock, allora o annotare la classe di test con @RunWith(MockitoJunitRunner.class), o utilizzare MockitoAnnotation.initMocks(this) (uno o l'altro, entrambi non sono richiesti se non sotto casi limite). Se si scelgono le annotazioni, non dimenticare @InjectMocks sull'oggetto di prova.

Infine, le vostre condizioni when fanno ciò che mi aspetterei che facessero - quelle dovrebbero andare bene.