web-dev-qa-db-fra.com

Test unitaire d'une méthode de vide

Afin de corriger un bogue dans une application, j'ai modifié une méthode nommée postLogin en ajoutant un appel à une méthode existante nommée getShoppingCart.

Code

protected void postLogin() {
  getShoppingCart();
}

Cependant, je ne sais pas quelle est la meilleure façon d'écrire un test unitaire pour postLogin.

approche 1

Utilisez la vérification de Mockito pour simplement vérifier que la méthode a été appelée.

verify(mock).getShoppingCart();

approche 2

Testez l'effet secondaire de l'appel de méthode en récupérant la valeur du panier de l'utilisateur.

AssertNotNull(user.getShoppingCart());

Une approche est-elle meilleure que l'autre?

15
A_B

Je préfère généralement la méthode 2.

Pourquoi? Parce que, vous voulez que postLogin change un état de votre système, mais comment il accomplit cela (et quelles méthodes il appelle en interne pour cela) n'est qu'un détail d'implémentation, rien sur quoi votre test unitaire ne devrait faire d'hypothèses. Il vaut donc mieux faire votre test en vérifiant simplement l'état final.

18
Doc Brown

Je changerais getShoppingCart en quelque chose comme initializeShoppingCart, le but de la méthode devrait être clair pour quiconque la lit sans avoir besoin de vérifier ce que fait la méthode et des effets secondaires comme celui-ci peuvent provoquer un comportement surprenant pour les utilisateurs de la méthode.

Si getShoppingCart est dans une autre classe et qu'il est déjà testé unitaire, j'utiliserais l'approche 1 - pas besoin de tester à nouveau ce qui a déjà été testé. Dans ce cas, nous sommes sûrs que getShoppingCart fonctionne correctement et nous voulons seulement nous assurer qu'il est appelé à partir de postLogin, donc si quelqu'un à l'avenir supprime cet appel, le test échouera.

Si getShoppingCart est une méthode privée qui ne peut pas être testée par elle-même, j'utiliserais l'approche 2, pour m'assurer que lorsque postLogin est appelé, la fonctionnalité souhaitée de getShoppingCart est exécutée comme prévu.

4
Nastya S

Lorsque vous testez un appel de fonction (vide ou non) qui a un effet secondaire, il est plus complet de tester que l'effet secondaire se produit non seulement, mais pour vérifier que l'effet secondaire (sortie du système ou changement d'état) est celui souhaité.

1
hotpaw2

Je ne discuterai pas de votre conception, mais dans votre cas, j'opterais pour la première approche, car le test unitaire sert à tester quelles méthodes font techniquement quel que soit leur travail dans le domaine, c'est-à-dire ce que fait votre méthode postLogin ? Techniquement, il appelle getShoppingCard donc vous devez tester qui appelle vraiment getShoppingCard, je créerais également un autre test pour getShoppingCard pour tester ce qu'il fait et s'il a des effets secondaires Je vais le vérifier dans ce nouveau test.

0
La VloZ Merrill

Vous avez un bogue dans postLogin. La première chose à faire est donc de créer un test unitaire qui, en appelant postLogin sans l'ensemble d'informations attendu, "échouera".

De l'idée ci-dessus, une autre alternative parmi les 2 proposées est d'injecter les informations sur le panier comme paramètre. Si vous ne disposez pas des informations correctes, vous lancez une exception non vérifiée. Cela montrera clairement que sans les détails corrects, votre méthode est vouée à l'échec.

Cela nécessitera un petit changement où le client appelant le postLogin en ce moment doit également transmettre les informations du panier. Pour moi, c'est toujours cohérent maintenant que vous voyez qu'ils sont couplés. Ce couplage sera effectué par l'appelant.

Ensuite, vous n'auriez même pas besoin de tester getShoppingCart dans postLogin car la vraie méthode testée est postLogin. C'est celui qui a le bogue et le seul qui nécessite une correction et une validation appropriées. Avec la dépendance injectée, vous pourrez le tester facilement dans des conditions différentes et confirmer qu'aucune erreur n'est levée.

0
gumol