Disons que je commence à développer un jeu de rôle avec des personnages qui attaquent d'autres personnages et ce genre de choses.
En appliquant TDD, je fais quelques cas de test pour tester la logique à l'intérieur de la Character.receiveAttack(Int)
méthode. Quelque chose comme ça:
@Test
fun healthIsReducedWhenCharacterIsAttacked() {
val c = Character(100) //arg is the health
c.receiveAttack(50) //arg is the suffered attack damage
assertThat(c.health, is(50));
}
Disons que j'ai 10 méthodes de test receiveAttack
. Maintenant, j'ajoute une méthode Character.attack(Character)
(qui appelle receiveAttack
méthode), et après quelques cycles TDD la testant, je prends une décision: Character.receiveAttack(Int)
devrait l'être private
.
Que se passe-t-il avec les 10 cas de test précédents? Dois-je les supprimer? Dois-je garder la méthode public
(je ne pense pas)?
Cette question n'est pas de savoir comment tester des méthodes privées, mais comment les gérer après une nouvelle conception lors de l'application de TDD
la source
internal
ou l'équivalent de votre langue pour éviter qu'elle ne soit exposée. En fait, la réponse de Kevin Cline est ce genre d'approche.Réponses:
Dans TDD, les tests servent de documentation exécutable de votre conception. Votre conception a changé, alors évidemment, votre documentation doit aussi!
Notez que, dans TDD, la seule façon dont la
attack
méthode aurait pu apparaître, est le résultat de l'échec d'un test. Ce qui signifie,attack
est testé par un autre test. Ce qui signifie qu'indirectementreceiveAttack
est couvert parattack
les tests de. Idéalement, toute modification apportée àreceiveAttack
devrait casser au moins l'un desattack
tests de.Et si ce n'est pas le cas, alors il y a des fonctionnalités
receiveAttack
qui ne sont plus nécessaires et ne devraient plus exister!Donc,
receiveAttack
étant déjà testéattack
, peu importe que vous continuiez ou non vos tests. Si votre infrastructure de test facilite le test de méthodes privées et si vous décidez de tester des méthodes privées, vous pouvez les conserver. Mais vous pouvez également les supprimer sans perdre la couverture et la confiance des tests.la source
Si la méthode est suffisamment complexe pour nécessiter des tests, elle doit être publique dans une classe. Vous refactorisez donc:
à:
Déplacez le test actuel de X.complexity vers ComplexityTest. Ensuite, envoyez X.quelque chose en se moquant de Complexité.
D'après mon expérience, la refactorisation vers des classes plus petites et des méthodes plus courtes rapporte d'énormes avantages. Ils sont plus faciles à comprendre, à tester et finissent par être réutilisés plus que ce à quoi on pourrait s'attendre.
la source
this.health = this.health - attackDamage
). Peut-être que l'extraire dans une autre classe est une solution sur-conçue, pour le moment.Il faut garder à l'esprit que la décision que vous prenez est de supprimer une méthode de l'API . La courtoisie de la rétrocompatibilité suggérerait
Les tests sont supprimés / ou remplacés lorsque votre API ne prend plus en charge la méthode. À ce stade, la méthode privée est un détail d'implémentation que vous devriez pouvoir refactoriser.
À ce stade, vous revenez à la question standard de savoir si votre suite de tests doit accéder directement aux implémentations, plutôt interagir uniquement via l'API publique. Une méthode privée est quelque chose que nous devrions pouvoir remplacer sans que la suite de tests ne gêne . Je m'attendrais donc à ce que le couple de tests disparaisse - soit retiré, soit déplacé avec l'implémentation vers un composant testable séparément.
la source