Je pense comprendre la définition des tests basés sur l'état/l'interaction (lire le truc de Fowler, etc.). J'ai trouvé que j'ai commencé basé sur l'état, mais j'ai fait plus d'interaction basée et je suis un peu confus sur la façon de tester certaines choses.Tests d'état/d'interaction et confusion sur le mélange (ou l'abus)
J'ai un contrôleur dans MVC et une action appelle un service de refuser un paquet:
public ActionResult Deny(int id)
{
service.DenyPackage(id);
return RedirectToAction("List");
}
Cela me semble clair. Fournissez un service de simulation, vérifiez qu'il a été appelé correctement, terminé.
Maintenant, j'ai une action pour une vue qui permet à l'utilisateur d'associer un certificat avec un package:
public ActionResult Upload(int id)
{
var package = packageRepository.GetPackage(id);
var certificates = certificateRepository.GetAllCertificates();
var view = new PackageUploadViewModel(package, certificates);
return View(view);
}
Ce que je suis un peu perplexe sur. Je fais des tests de style Spec (éventuellement incorrectement) donc pour tester cette méthode j'ai une classe et ensuite deux tests: vérifier que le référentiel de paquetages a été appelé, vérifier que le référentiel de certificats a été appelé. Je veux en fait qu'un tiers teste pour vérifier que le constructeur a été appelé mais n'a aucune idée de comment faire ça! J'ai l'impression que c'est complètement faux.
Donc, pour le test basé sur l'état, je passerais dans l'ID, puis tester la vue ActionResult. D'accord, c'est logique. Mais n'aurais-je pas un test sur le constructeur PackageUploadViewModel? Donc, si j'ai un test sur le constructeur, alors une partie de moi voudrait juste vérifier que j'appelle le constructeur et que le retour d'action correspond à ce que le constructeur retourne. Maintenant, une autre option que je peux penser est que j'ai un PackageUploadViewModelBuilder (ou quelque chose de tout aussi bêtement nommé) qui dépend des deux dépôts, puis je passe juste l'ID à une méthode CreateViewModel ou quelque chose. Je pourrais alors me moquer de cet objet, vérifier tout, et être heureux. Mais ... eh bien ... ça semble extravagant. Je fais quelque chose de simple ... pas simple. De plus, controller.action (id) renvoyant builder.create (id) semble ajouter une couche sans raison (le contrôleur est responsable de la construction des modèles de vue .. non?)
Je ne sais pas ... Je pense plus de tests basés sur l'état est nécessaire, mais j'ai peur que si je commence à tester les valeurs de retour, si la méthode A peut être appelée dans 8 contextes différents, je vais avoir une explosion de test avec beaucoup de répétitions. J'avais utilisé des tests basés sur l'interaction pour passer certains de ces contextes à la méthode B de sorte que tout ce que j'ai à faire est de vérifier la méthode A appelée méthode B et la méthode B testée afin que la méthode A puisse juste faire confiance à ces contextes. Les tests basés sur l'interaction construisent donc cette hiérarchie de tests, mais les tests basés sur l'état vont l'aplatir.
Je n'ai aucune idée si cela avait un sens.
Wow, c'est long ...
Yah, l'exemple Deny était super clair que je devrais tester les interactions. Le télécharger un était ce qui me déroute. J'étais sur la clôture avec les modèles de xUnit (il est apparemment énorme et j'avais peur de l'acheter et de ne pas le lire) mais le renvoi pourrait en valoir la peine. Une chose, et cela pourrait être juste un détail, mais pour tester le Upload (ce qui me fait réaliser quel nom terrible que Action est ... refactor time), je pourrais (a) créer la vue dans le test manuellement et vérifiez que les deux vues sont égales ou (b) vérifiez que chaque propriété de la vue est égale à ce qu'elle devrait être. Préférences? – anonymous
@eyston: Le livre de Roy Osherove "L'art des tests unitaires" est une bonne alternative si vous avez peur que l'autre soit trop gros en ce moment - mais vous devriez toujours prévoir de le lire à une date ultérieure. –
@eyston: Peu importe que vous décidiez de comparer deux vues, ou toutes leurs propriétés indépendamment, vous faites généralement une assertion logique. C'est plus facile si vous pouvez simplement comparer deux objets complexes entre eux, mais cela n'est possible que si la classe remplace Equals de la manière correcte. Que vous le vouliez ou non, vous devriez décider en fonction de la façon dont vous souhaitez modéliser l'API elle-même.En d'autres termes: ne remplacez pas Equals juste pour tester, mais si vous avez déjà écrasé Equals de la manière souhaitée, vous pouvez certainement l'utiliser pour faire des assertions. –