Comment tester les méthodes privées ?
Cette question se pose lorsqu’on se met au Test Driven Developpement (TDD). Deux origines possibles : la méthodologie n’a pas été suivie à la lettre et elle nous puni, ou bien nous essayons de faire du TDD sur du code existant, non testé. Dans les deux cas, vous avez un problème de conception.
Conception émergente.
Vous suivez strictement les règles du TDD. Vous écrivez un test : il échoue. Vous faites un copié-collé bien sale : le test passe. Vous refactorez : vous créez une méthode privée, et vous l’appelez deux fois. Les méthodes privées ainsi créées sont testées à deux endroits, un pour chaque méthode publique. Si vous suivez strictement TDD, vous écrivez vos tests avant vos méthodes. Vous ne devriez donc jamais avoir à vous poser la question « mais comment tester cette méthode ? »
Vous suivez les règles strictement, et vous tombez tout de même sur la question ? Vous avez probablement commencé par écrire le coeur de votre application, sans penser à son intégration. Et celle ci vous réserve des surprises. Jetez votre code, écrivez un petit test, et faites-le passer ! Sinon, lisez le prochain paragraphe.
J’ai une méthode privée non testée dans mon code. Et maintenant ?
Ce sont des choses qui arrivent chaque jour. Selon votre conception, vous avez trois options : rendre votre méthode publique (voire même l’exposer en tant que service dans une classe différente), la tester via une méthode publique, ou changer sa visibilité en protected (ou package).
Si votre méthode publique est en réalité un service, qui pourrait être réutilisé, pourquoi ne pas la rendre publique ? C’est toujours une option. Vous pouvez même l’extraire dans une classe à part, afin de mieux suivre le Principe de Responsabilité Unique (Single Responsibility Principle).
Si ce n’est pas un service, pourquoi voulez-vous tester cette méthode ? Parce qu’elle est utilisée par une autre méthode de la même classe ? Bien. Traitez la comme si elle faisait partie du code de cette autre méthode. Ecrivez un test pour la méthode publique : cela testera votre méthode privée également. Et vos outils de couverture de code sauront l'identifier.
Parfois, un bug est situé dans une méthode privée. Et vous ne voulez pas recréer tout le contexte nécessaire à appeler la méthode publique. Dans ce cas, considérez la première option : pouvez-vous extraire votre méthode privée dans une classe à part ? Si ce n’est pas le cas, vous pouvez toujours changer la visibilité. Votre méthode est maintenant accessible pour tout le package. Vous pouvez donc écrire une classe de test qui y accèdera.
Il existe d'autres possibilités. Si vous êtes en java, vous pouvez utiliser la réflexion. Si vous êtes en Ruby, vous pouvez utiliser la commande 'send'. Ce sont des commandes avancées, qu'il faut employer avec précaution.
Se poser la question « comment tester une méthode privée » devrait lever une alarme. Vous pourriez surement utiliser un service au lieu d’une méthode privée. Si non, elle devrait être testée comme s’il s’agissait du corps même de la méthode publique l’utilisant.