Tester le code en général n'est pas facile. Si c'était le cas, nous l'aurions fait il y a longtemps et nous ne nous en serions pas beaucoup occupés au cours des 10 à 15 dernières années. L'une des plus grandes difficultés a toujours été de déterminer comment tester du code écrit de manière cohérente, bien factorisée et testable sans rompre l'encapsulation. Le directeur de BDD suggère que nous nous concentrions presque entièrement sur le comportement et, à certains égards, semble suggérer que vous n'avez pas vraiment besoin de vous soucier des détails intérieurs dans une large mesure, mais cela peut souvent rendre les choses assez difficiles à tester s'il y en a. de nombreuses méthodes privées qui "trucent" de manière très cachée, car cela peut augmenter la complexité globale de votre test pour traiter tous les résultats possibles à un niveau plus public.
La moquerie peut aider dans une certaine mesure, mais là encore, elle est plutôt orientée vers l'extérieur. L'injection de dépendances peut également fonctionner très bien, encore une fois avec des simulations ou des tests doubles, mais cela peut également nécessiter que vous exposiez des éléments soit via une interface, soit directement, que vous auriez sinon préféré préférer rester masqués - cela est particulièrement vrai si vous souhaitez avoir un bon niveau de sécurité paranoïaque sur certaines classes de votre système.
Pour moi, le jury n'est toujours pas sur la question de savoir si vous devez concevoir vos cours pour qu'ils soient plus facilement testables. Cela peut créer des problèmes si vous devez fournir de nouveaux tests tout en conservant le code hérité. J'accepte que vous devriez pouvoir tester absolument tout dans un système, mais je n'aime pas l'idée d'exposer - même indirectement - les internes privés d'une classe, juste pour que je puisse écrire un test pour eux.
Pour moi, la solution a toujours été d'adopter une approche assez pragmatique et de combiner un certain nombre de techniques adaptées à chaque situation spécifique. J'utilise beaucoup de doublons de test hérités pour exposer les propriétés internes et les comportements de mes tests. Je me moque de tout ce qui peut être attaché à mes classes, et là où cela ne compromettra pas la sécurité de mes classes, je fournirai un moyen de remplacer ou d'injecter des comportements à des fins de test. J'envisagerai même de proposer une interface plus événementielle si cela permet d'améliorer la capacité de tester le code
Là où je trouve un code "non testable" , je cherche à voir si je peux refactoriser pour rendre les choses plus testables. Lorsque vous avez beaucoup de code privé faisant des trucs cachés dans les coulisses, vous trouverez souvent de nouvelles classes en attente d'être éclatées. Ces classes peuvent être utilisées en interne, mais peuvent souvent être testées de manière indépendante avec moins de comportements privés, et par la suite souvent moins de couches d'accès et de complexité. Une chose que je prends soin d'éviter, cependant, est d'écrire du code de production avec un code de test intégré. Il peut être tentant de créer des " cosses de test " qui aboutissent à inclure des horreurs telles que if testing then ...
, ce qui indique un problème de test pas complètement déconstruit et incomplètement résolu.
Vous pourriez trouver utile de lire le livre xUnit Test Patterns de Gerard Meszaros , qui couvre tout ce genre de choses avec beaucoup plus de détails que je ne peux en parler ici. Je ne fais probablement pas tout ce qu'il suggère, mais cela aide à clarifier certaines des situations de test les plus difficiles à gérer. À la fin de la journée, vous voulez être en mesure de satisfaire vos exigences de test tout en appliquant vos conceptions préférées, et il est utile d'avoir une meilleure compréhension de toutes les options afin de mieux décider où vous devrez peut-être faire des compromis.