J’ai lu ce post sur la façon de tester des méthodes privées. J’ai habituellement ne Testez pas eux, parce que j’ai toujours pensé que c’est plus rapide pour tester uniquement les méthodes publiques qui seront appelées à partir en dehors de l’objet. Vous tester des méthodes privées ? Je devrais toujours les tester ?
Réponses
Trop de publicités?Je n'ai pas de test de l'unité des méthodes privées. Une méthode privée est un détail d'implémentation qui doivent être cachés aux utilisateurs de la classe. Essais de méthodes privées pauses de l'encapsulation.
Si je trouve que la méthode privée est vaste ou complexe ou assez important de demander à ses propres tests, je viens de le mettre dans une autre classe et de le rendre public (Méthode de l'Objet). Ensuite, je peux facilement tester le déjà-privé-mais-maintenant-méthode publique qui vit maintenant de sa propre classe.
Quel est le but de l'essai?
La majorité des réponses sont en train de dire que les méthodes privées sont des détails d'implémentation qui ne le font pas (ou au moins ne devrait pas), tant que l'interface publique est bien testé et de travail. C'est tout à fait correcte si votre seul but pour le test est de garantir que l'interface publique des œuvres.
Personnellement, mon utilisation principale pour le code de test est de s'assurer que les futures modifications du code ne provoquent pas de problèmes et à l'aide de mon débogage efforts s'ils le font. Je trouve que les tests de dépistage du privé méthodes tout aussi soigneusement que l'interface publique (si pas plus!) vise cet objectif.
Prendre en compte: Vous avez Une méthode publique qui appelle la méthode B. A et B à la fois de rendre l'utilisation de la méthode de C. C est changé (peut-être par vous, peut-être par un fournisseur), provoquant Une pour commencer à défaut de ses tests. Ne serait-il pas utile d'avoir des tests pour B aussi, même si c'est privé, de sorte que vous savez si le problème est dans l'utilisation de C, B l'utilisation de C, ou les deux?
J'ai tendance à suivre les conseils de Dave Thomas et Andy Hunt dans leur livre Pragmatique de l'Unité de Test:
En général, vous ne voulez pas briser l'encapsulation pour l'amour de de tests (ou en tant que Maman avait l'habitude de dire, "ne pas exposer vos soldats!"). La plupart des du temps, vous devriez être en mesure de tester une classe par l'exercice de ses les méthodes publiques. Si il est important de fonctionnalités qui est caché derrière privés ou à accès protégé, qui pourrait être un signe d'avertissement que il y a une autre classe il y a du mal à sortir.
Mais parfois, je ne peux pas m'empêcher de tester les méthodes privées, car il me donne ce sentiment de réconfort que je suis en train de construire un complètement le programme solide.
J'ai en quelque sorte de se sentir obligé de tester les fonctions privées comme je suis de plus en plus et l'un de nos derniers QA recommandation dans notre projet:
Pas plus de 10 dans la complexité cyclomatique par fonction.
Maintenant du côté de l'effet de l'application de cette politique est que beaucoup de mes très grandes fonctions publiques qui se divisent en beaucoup plus ciblée, mieux nommée privé de la fonction.
La fonction publique est toujours là (bien sûr), mais est essentiellement réduite à appelé tous les "sous-fonctions'
Qui est vraiment cool, parce que la pile des appels est maintenant beaucoup plus facile à lire (au lieu d'un bug au sein d'une grande fonction, j'ai un bug dans un sous-sous-fonction avec le nom de l'ancien fonctions dans la pile d'appels pour m'aider à comprendre comment j'en suis arrivé là")
Cependant, il semble plus facile de test unitaire directement celles privé des fonctions, et de laisser le test de la grande à la fonction publique, à une sorte "d'intégration" test où un scénario qui doit être abordé.
Juste mes 2 cents.
Oui, je ne test privé des fonctions, car même s'ils sont testés par vos méthodes, c'est sympa en mode TDD (Test Driven Design) pour le test de la plus petite partie de l'application. Mais les fonctions ne sont pas accessibles lorsque vous êtes dans votre unité de test de la classe. Voici ce que nous faisons pour tester nos méthodes privées.
Pourquoi ne nous ont privé de méthodes?
Privé des fonctions principalement existe dans notre classe, car nous voulons créer un code lisible dans nos méthodes publiques. Nous ne voulons pas que l'utilisateur de cette classe d'appeler ces méthodes directement, mais au travers de nos méthodes publiques. Aussi, nous ne voulons pas changer leur comportement lors de l'extension de la classe (dans le cas d'une protection), donc c'est un privé.
Quand on code, nous utilisons le test-driven-conception (TDD). Cela signifie que, parfois, on tombe sur un morceau de la fonctionnalité qui est privé et que vous souhaitez tester. Les fonctions privées ne sont pas testables dans phpUnit, parce que nous ne pouvons pas accéder à la classe de Test (ils sont privés).
On pense ici, 3 solutions:
1. Vous pouvez tester vos soldats par le biais de vos méthodes publiques
Avantages
- Simple unité de test (pas de "hacks" nécessaire)
Inconvénients
- Programmeur doit comprendre la méthode publique, alors qu'il veut seulement pour tester la méthode privée
- Vous n'êtes pas test le plus petit testable partie de l'application
2. Si le privé est si important, alors peut-être que c'est un codesmell pour créer une nouvelle catégorie distincte pour elle
Avantages
- Vous pouvez restructurer ce à une nouvelle classe, parce que si c'est que important, d'autres classes peuvent avoir besoin de trop
- Le testable unité est maintenant une méthode publique, donc testable
Inconvénients
- Vous ne voulez pas créer une classe, si il n'est pas nécessaire, et utilisées uniquement par la classe dans laquelle la méthode est à venir à partir de
- Le potentiel de perte de performance en raison de l'ajout de frais généraux
3. Changer le modificateur d'accès à l' (final) protégé
Avantages
- Vous test le plus petit testable partie de l'application. Lorsque à l'aide de final protégées, la fonction ne sera pas substituables (juste comme un privé)
- Aucune perte de performance
- Pas de surcharge
Inconvénients
- Vous êtes à la modification d'un accès privé à protégé, ce qui signifie qu'il est accessible par les enfants
- Vous avez encore besoin d'un Simulacre de classe dans votre classe de test pour l'utiliser
Exemple
class Detective {
public function investigate() {}
private function sleepWithSuspect($suspect) {}
}
Altered version:
class Detective {
public function investigate() {}
final protected function sleepWithSuspect($suspect) {}
}
In Test class:
class Mock_Detective extends Detective {
public test_sleepWithSuspect($suspect)
{
//this is now accessible, but still not overridable!
$this->sleepWithSuspect($suspect);
}
}
Donc, notre unité de test peut maintenant appeler test_sleepWithSuspect à l'épreuve de notre ancienne fonction.