2010-07-29 13 views
0

Le projet que je viens de rejoindre utilise assez largement le modèle de commande pour gérer les appels dans les couches logiques métier du projet.Stratégie de sortie de dépendance statique

Les couches logiques métier sont construites en tant que gestionnaires statiques appelant des fournisseurs. Les commandes appellent ensuite ces gestionnaires statiques. L'équipe veut améliorer la couverture de test, et je voudrais que nous nous dirigeons plus vers le vrai TDD mais l'utilisation de gestionnaires statiques signifie qu'il y a une dépendance codée en dur dans les commandes et il n'y a aucun moyen d'injecter les gestionnaires dépendances et il est donc très difficile de tester les commandes isolément.

Est-ce que quelqu'un a de bonnes suggestions pour une stratégie pour nous de passer à un modèle de commande plus testable en gardant à l'esprit qu'il y a beaucoup de commandes déjà utilisées.

La méthode de traitement ci-dessous serait appelée quand execute est appelée sur la commande. Ce serait la méthode à tester. Ceci est un exemple typique de l'utilisation des gestionnaires statiques dans les classes de commande.

protected override bool Process() 
{ 
    this.user = SecurityHandler.ActivateUser(this.activationGuid); 
    bool success = this.user != null; 

    if (!success) 
    { 
     this.AddStatusMessage(StatusMessageType.Error, "/Commands/Security/ActivateUserCommand/IncorrectLink", true); 
    } 

    return success; 
} 
+0

l'exemple de code a aidé ... voir la mise à jour la réponse. – Gishu

Répondre

2

Les méthodes/champs statiques ont généralement un impact négatif sur la testabilité - car ils introduisent le risque que les tests ne soient pas isolés. Un test pourrait définir un champ statique, en changeant l'état initial de test2. Cela dit, il n'y avait rien dans le patron de commande qui nécessitait des gestionnaires statiques .. donc je pense que c'est une implémentation personnalisée. Je voudrais voir un exemple de code pour une réponse plus courte.

Il n'y a pas de solution de facilité ... déplacez les parties statiques dans une autre classe/objet et transmettez-les dans les objets qui doivent y accéder. Cela peut signifier l'ajout d'un paramètre aux méthodes qui utilisent actuellement un appel TypeName.StaticField pour obtenir les données. Mise à jour (pour l'extrait de code affiché): Je ne vois pas le motif de commande ici .. de toute façon pour obtenir la méthode en cours de test.

  • Est-ce que SecurityHandler.ActivateUser a des effets secondaires? Est-ce que l'appeler une seconde fois diffère d'une manière quelconque de l'appeler la première fois? Si ce n'est pas le cas (c'est-à-dire un appel de service pur) alors ne vous inquiétez pas à ce sujet.
  • si ActivateUser a des effets secondaires, alors vous devez faire un peu de travail. Autrement dit, transformez les méthodes statiques en méthodes d'instance et transmettez une instance de SecurityHandler au type conteneur de Process(). Vous pouvez le transmettre en tant que paramètre de méthode à Process() ou à un ensemble de propriétés/ctor sur le type contenant. Choisissez ce que vous jugez approprié.
+0

L'extrait de code affiché est uniquement la méthode de processus appelée lorsque l'exécution est appelée sur la commande de base. Ce n'est pas la classe de commande entière, cet extrait est effectivement la méthode d'exécution de la classe de commande –

+0

Dans ce cas, le gestionnaire renvoie un utilisateur, mais il existe de nombreux cas différents qui ont tous des effets différents. Je voudrais finalement passer dans le gestionnaire et vérifier que la méthode appropriée a été appelée avec les paramètres appropriés, de sorte que votre partie 2 édition est ce qui doit arriver. Je vais étudier la possibilité de Typemock aujourd'hui comme suggéré par Grant pour voir si c'est une possibilité mais comme il dit que ce ne sera jamais une soluion idéale et refactoring pour injecter la dépendance est toujours la meilleure solution. –

+0

@Jet - Ok. Ca a du sens maintenant ... Ma recommandation serait alors de passer le gestionnaire en tant que paramètre ctor aux sous-classes spécifiques de Command. – Gishu

2

Dependecy Injection (inversion de contrôle)

dépendances statiques sont mauvaises odeurs, et généralement on peut utiliser DI/IoC pour enlever cette mauvaise odeur. Trouver un cadre DI/IoC que vous aimez et l'utiliser.

+0

Salut nanda, oui il est clair que DI est la voie à suivre, mais comme je l'ai dit il y a beaucoup de commandes déjà en jeu, donc idéalement, nous ne voudrions pas avoir à refactoriser chacun d'entre eux. Évidemment, il se peut que nous devions le faire, mais je me demandais si quelqu'un ici pouvait savoir comment nous pourrions faire cela sans refactoriser toutes les commandes. –

+1

La bonne nouvelle du framework DI est qu'il ne vous force pas à l'utiliser partout. Refactoriser un peu et déployer. La prochaine fois que vous refactoriser le prochain et passer à autre chose. – nanda

+0

Je pense que votre réponse est d'aller à la dure, mais en petits pas faciles. Je pense que finalement cela doit être la façon de le faire. –

0

Bien que cela ne fonctionne pas en termes de modèles de conception, si vous voulez augmenter les tests maintenant, vous pouvez toujours utiliser quelque chose comme Typemock Isolator ou Telerik JustMock, qui vous permettent de se moquer des classes statiques, alors que vous convertissez loin votre code de la conception actuelle. (Ce sont des produits commerciaux).Je ne ferais pas cela moi-même, car il y a un risque que vous commenciez à vous fier à eux et que vous n'ayez pas à refactoriser votre code pour le rendre testable - une des choses que j'aime dans TDD/test automatisé est qu'il vous oblige à avoir du code qui est couplé de manière lâche et suit certains principes de conception, et des outils comme ceux-ci peuvent en tenir compte.

+0

Merci Grant, explorera la possibilité d'utiliser Typemock aujourd'hui. –

+0

Quand je dis 'je ne le ferais pas moi-même', ce que je veux vraiment dire c'est que je ne ferais pas ça à moins qu'il n'y ait pas de meilleure alternative. Certainement mieux d'utiliser ces outils que de ne pas faire de test unitaire! –