web-dev-qa-db-fra.com

Comment puis-je tester mon service web REST?)

Je suis nouveau dans les tests unitaires, j'en ai une REST méthode web qui appelle simplement DB et remplit un DTO. Le pseudo-code est

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

Mon doute est de savoir comment écrire des tests pour ces méthodes et le type de tests (intégration/unité) à inclure. Et pour les tests unitaires, faut-il frapper la base de données. Si c'était le cas et que je transmettais un identifiant client et que je fais peu d'assertions, les données pourraient éventuellement changer, ce qui entraînerait des échecs.

Je pense que je manque quelque chose ici pour comprendre ces concepts.

16
Sunny

Pendant les tests unitaires, vous ne devez pas tester avec une base de données, ou du moins, pas avec une base de données que vous n'avez pas préparée pour les tests unitaires. Tester avec une base de données, et en tant que tel, tester simultanément différentes couches de votre application est généralement considéré comme tests d'intégration . Avec les tests unitaires, vous êtes censé tester uniquement ce que fait votre méthode, ce qu'elle renvoie en fonction de différents paramètres et quand (ou non) elle doit échouer.

Il est très attendu que dans votre méthode vous fassiez des appels aux méthodes [~ # ~] x [~ # ~] d'autres classes. Vous ne testez pas ces méthodes [~ # ~] x [~ # ~] donc ce que vous devez faire est de simuler ces méthodes.

Je suppose que vous écrivez votre code en Java, dans ce cas, vous avez d'excellents cadres de simulation tels que Mockito qui peuvent vous être utiles. Que vous utilisiez ou non un cadre de simulation est votre choix, je dirai simplement qu'il vous fera gagner beaucoup de temps et celui que j'ai mentionné au moins n'est vraiment pas compliqué.

Si vous voulez simplement écrire votre propre maquette pour expérimenter, alors supposez que vous avez la classe CustomerRepository suivante:

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

Vous pouvez écrire votre propre classe CustomerRepository simulée et sale de la manière suivante:

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); 
  }
 }
}

Ensuite, dans votre cas de test, vous remplacez essentiellement votre instance "standard" de CustomerRepository par une instance simulée qui vous permettra de tester votre méthode pour différents résultats de 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.
  }
}

En règle générale, chaque méthode de test ne doit tester qu'une seule chose, ce qui permet de garder vos tests petits et concentrés sur une seule tâche.

Je vais le répéter :-) L'écriture d'une classe moquée entière prend un certain temps comme vous le voyez. Envisagez d'utiliser un cadre de simulation, moins on écrit de code, moins on fait d'erreurs , non? Se moquer d'une méthode qui lève une exception ou renvoie une valeur donnée pour un paramètre donné est un jeu d'enfant et prend 2 ou 3 lignes (avec mockito au moins)

J'espère que cela vous aidera à tester votre méthode REST.

18
Jalayn