Nous utilisons StructureMap dans un nouveau projet de développement logiciel. L'un des membres de l'équipe a mis en œuvre un test unitaire qui teste essentiellement la configuration du conteneur StructureMap . Il le fait en procédant comme suit;
- Compte le nombre d'instances d'assemblys configurés pour les classes dans notre espace de noms d'application.
- Définit les instances attendues au niveau de la classe
- Affirme que les instances attendues correspondent au nombre total d'instances trouvées.
- Affirme que les instances attendues correspondent à celles définies dans le test
Un exemple de ceci est;
var repositories = container.GetAllInstances<IEnvironmentRepository>();
Assert.AreEqual(1, repositories .Count());
foundInstances = foundInstances + repositories .Count();
Nous avons également des «tests unitaires» pour la classe suivante;
public MyClass(IEnvironmentRepository environmentRepository)
{
}
Dans ces tests, nous nous moquons de IEnvironmentRepository, donc nous ne l'injecterions pas du conteneur comme cela se produirait dans le système actif.
Un collègue a ignoré le test unitaire dans la configuration structuremap avec un commentaire du type "Le test unitaire teste uniquement sa propre configuration". C'était évidemment le but du test et à mon avis c'est parfaitement valable. J'ai demandé au gars qui a ignoré le test de supprimer la configuration de structuremap IEnvironmentRepository
(avec le test toujours ignoré) et d'exécuter la suite de tests unitaires complète, ils ont tous réussi. Nous avons ensuite exécuté l'application et elle est tombée car la configuration du conteneur n'était plus valide. À mon avis, cela prouvait la valeur du test, mon collègue n'était toujours pas d'accord. Il a simplement déclaré que nous ne devrions pas tester la configuration, mais je considère que cela relève bien du mandat d'un test unitaire.
Donc, un certain nombre de questions;
- Est-ce un test unitaire valide - Nous testons la configuration de notre conteneur, pas que la structure de carte fonctionne (mais je peux voir le chevauchement)
- Sinon, comment pouvez-vous valider la configuration sans la tester. Comment pouvez-vous empêcher quelqu'un de supprimer accidentellement une ligne de code requise et de l'archiver?
- Le
MyClass
test unitaire doit-il résoudre l'instance deIEnvironmentRepository
du conteneur et le transmettre?
la source
Réponses:
Il s'agit d'un test automatisé parfaitement valide. Je les appelle des "tests d'architecture" car ils vérifient la solidité des composants squelettiques de votre base de code.
Le conteneur IoC est-il capable de résoudre et de composer toutes les arborescences d'objets dans l'application? Le mappeur automatique peut-il mapper entre tous ses objets enregistrés sans échec? La couche centrale d'une architecture Oignon ne fait-elle référence à rien d'extérieur?
Ces tests peuvent vous faire gagner beaucoup de temps lorsqu'un bogue de configuration se glisse, en pointant le coupable exact. De bons cadres vous donneront des messages d'erreur très précis sur ce qui ne va pas et vous les obtiendrez dès que vous exécuterez les tests (idéalement, en continu) au lieu d'être enfouis au fond d'une trace de pile d'exécution si vous êtes chanceux.
Qu'il s'agisse de tests unitaires ... probablement pas, mais ils fonctionnent toujours en mémoire pour la plupart et fonctionnent assez rapidement. Là encore, je ne sais pas, ce n'est pas comme s'il y avait une définition universellement acceptée du test unitaire.
la source
Le problème avec un test comme celui-ci qui teste les internes du programme, plutôt qu'une exigence de celui-ci. Est-ce que le test peut échouer même si le programme fonctionne comme requis.
Dans votre cas, chaque fois que vous modifiez la configuration du conteneur, vous avez peut-être une nouvelle dépendance à injecter, vous cassez votre test.
En outre, si vous ajoutez l'exigence de dépendance supplémentaire, mais oubliez de l'ajouter au conteneur et modifiez le test du conteneur. tout passera, mais votre programme plantera.
Un meilleur test automatisé serait de démarrer le programme et de voir s'il se bloque.
Vous devez détecter ces types d'erreur lors des tests d'intégration ou d'interface utilisateur, même s'ils tombent dans les tests unitaires.
Cela dit, la complexité croissante de la configuration des conteneurs est pénible. Peut-être que certains «mauvais» tests en valent la peine.
la source
Test unitaire du code de test. Tout ce qui est en dehors de cela est un "autre" test automatisé - appelez-le comme vous voulez. Vous semblez tester la configuration ici. Si la configuration peut changer en fonction de l'environnement, elle n'appartient pas à un test unitaire. Pensez à ajouter un attribut de test pour indiquer que le test est d'un type différent des autres tests.
la source
La responsabilité du conteneur d'injection de dépendance est de coller différents modules dans une application de travail .
Si vous écrivez des tests automatisés pour votre application - vous devriez avoir quelques "tests d'intégration (ou d'acceptation) qui exécutent des tests" de bout en bout ", qui testeront l'ensemble du pipeline de votre application, que tous les modules impliqués dans un cas de test particulier sont collés ensemble correctement .
Ces tests d'intégration échoueront donc si le conteneur d'injection de dépendance n'a pas été configuré correctement. Ce qui rend les tests unitaires pour le conteneur lui-même inutiles, car le test d'intégration devrait montrer d'éventuelles erreurs dans la configuration du conteneur.
Vous n'avez pas besoin de couvrir tous les cas de test possibles dans les tests d'intégration, juste un cas de test par fonctionnalité qui couvre le chemin complet de l'interface utilisateur à la base de données.
Si les cas de test d'intégration ne couvrent pas l'instanciation d'une dépendance particulière - vous ajoutez simplement celle-ci.
Avec les tests d'intégration, vous pouvez modifier librement les conteneurs sans réécrire les tests unitaires pour leur configuration.
la source
OMI, les réponses sont:
Est-ce un test unitaire valide - Nous testons la configuration de notre conteneur, pas que la structure de carte fonctionne (mais je peux voir le chevauchement)
Sinon, comment pouvez-vous valider la configuration sans la tester. Comment pouvez-vous empêcher quelqu'un de supprimer accidentellement une ligne de code requise et de l'archiver?
Le test unitaire MyClass doit-il résoudre l'instance de IEnvironmentRepository à partir du conteneur et le transmettre?
la source
UnitTest vérifie le comportement souhaité d'une unité en séparation .
Cela signifie que tout type de configuration ne fait pas partie des tests unitaires .
Néanmoins, vous devriez avoir des tests automatisés pour vos configurations, mais ce ne sont pas des UnitTests ...
la source