Come posso testare l'unità del mio servizio web REST?


16

Sono nuovo ai test unitari, ho un metodo web REST che chiama solo DB e popola un DTO. Lo pseudo codice è

public object GetCustomer(int id)
{
  CustomerDTO objCust = //get from DB
  return objCust;
}

Il mio dubbio è come scrivere i test per questi metodi e il tipo di test (Integrazione / Unità) da includere. E per unit test, deve colpire il DB. Se lo fosse e io passo un ID cliente e faccio poche asserzioni, i dati potrebbero cambiare alla fine con conseguente fallimento.

Penso che mi manchi qualcosa qui capendo questi concetti.


5
Nel codice che hai pubblicato, le cose da testare sono: (1) Puoi chiamare GetCustomer con un int come parametro. (2) Restituisce un oggetto CustomerDTO? (3) È quell'oggetto popolato dal DB come previsto. (4) Si verifica un comportamento previsto se chiamato con un int che non corrisponde a un cliente valido? Niente di tutto ciò ha ancora a che fare con REST. Quando sei pronto a scrivere il codice che risponde alle richieste RESTful, allora scriverai dei test per questo.
DavidO

@DavidO: "È quell'oggetto popolato dal DB come previsto." non è decisamente un test unitario (per quanto riguarda il codice OP). Questo è un test di integrazione.
Flater,

Sì hai ragione. Se potessi tornare indietro e cambiare il commento per menzionare che in un test di integrazione verificheresti il ​​componente DB, e altrimenti lo deriderei, farei quella modifica, ma la finestra di modifica per i commenti se 5 minuti e il commento è stato reso sei anni fa. :)
DavidO

Risposte:


18

Durante il test unitario non è previsto il test con un database o almeno non con un database non predisposto per il test unitario. I test con un database e, in quanto tali, testare contemporaneamente diversi livelli dell'applicazione sono visti come test di integrazione . Con i unit test dovresti testare solo ciò che fa il tuo metodo, cosa restituisce in base a parametri diversi e quando (o meno) dovrebbe fallire.

È molto probabile che nel tuo metodo tu faccia chiamate a metodi X da altre classi. Non stai testando questi metodi X , quindi quello che devi fare è deridere questi metodi.

Suppongo che tu stia scrivendo il tuo codice in Java, in quel caso hai grandi framework di derisione come Mockito che potrebbero esserti utili. Che tu scelga o meno un framework beffardo è la tua scelta, dirò solo che ti faranno risparmiare un sacco di tempo e quello che ho menzionato almeno non è davvero complicato.

Se vuoi solo scrivere il tuo finto esperimento, supponi di avere la seguente CustomerRepositoryclasse:

public class CustomerRepository {
 public CustomerDTO getCustomer(int id) {
   ...
 }
}

Puoi scrivere la tua CustomerRepositoryclasse derisa e sporca nel modo seguente:

public class MockedCustomerRepository extends CustomerRepository {
 public boolean bThrowDatabaseException;
 public boolean bReturnNull;
 public boolean bReturnCustomerWrongId;
 public boolean bReturnCustomerWithId;
 public CustomerDTO getCustomer(int id) {
  if(bThrowDatabaseException) { 
    throw new DatabaseException("xxx"); 
  } else if(bReturnNull) { 
    return null; 
  } else if(bReturnCustomerWrongId) { 
    throw new CustomerNotExistException(id);
  } else if(bReturnCustomerWithId) { 
    return new CustomerDTO(id); 
  }
 }
}

Quindi, nel tuo caso di test sostanzialmente sostituisci l'istanza "standard" di CustomerRepositorycon un'istanza beffarda che ti permetterà di testare il tuo metodo per vari esiti di getCustomer:

public class CustomerRestTest {
  public void testGetCustomer_databaseFailure() {
    MockedCustomerRepository dto = new MockedCustomerRepository();
    dto.bThrowDataBaseException = true;
    yRestClass rest = new MyRestClass();
    rest.dto = dto;
    rest.getCustomer(0);
    // depending on what you do in your getCustomer method, you should check if you catched the exception, or let it pass, etc.. Make your assertions here

  public void testGetCustomer_customerNotExist() {
    // etc.
  }
}

In generale, ogni metodo di test dovrebbe testare solo una cosa, questo aiuta a mantenere i test piccoli e focalizzati su un compito.

Lo ripeterò :-) Scrivere un'intera classe derisa richiede del tempo come vedi. Prendi in considerazione l'utilizzo di un framework beffardo, meno si scrive codice, meno errori si commettono , giusto? Deridere un metodo che genera un'eccezione o restituisce un determinato valore per un determinato parametro è un gioco da ragazzi e prende 2 o 3 righe (con almeno mockito)

Spero che ti aiuti a testare il tuo metodo REST.


4
Di solito non hai una logica all'interno delle tue classi DTO, specialmente nessuna che interagisca con la tua memoria dati.
JustAnotherUserYouMayKnowOrNon

1
Era solo un esempio, ma hai assolutamente ragione. Cambierò gli esempi in modo che si adattino meglio alla teoria.
Jalayn,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.