Question

Il y a un mois, je fini de lire le livre « Art of Testing Unit » et aujourd'hui j'ai finalement eu le temps de commencer à utiliser Rhino Mocks avec l'unité à tester un service qui envoie / reçoit des messages aux périphériques (UDP) et enregistre / charge les données de la base de données.
Bien sûr que je veux isoler la base de données et la communication UDP.

Par exemple, pour un accès de base de données, nous avons certaines classes avec des méthodes statiques, nous allons les appeler:

  • AreaADBAccess
  • AreaBDBAccess
  • AreaCDBAccess

Ces classes ont des méthodes statiques qui exécutent l'accès base de données.
Pour pouvoir les bouchonner je fait leurs méthodes publiques virtuelle.

Alors j'ai commencé refactorisation du code pour être en mesure de remplacer l'instance de ces classes sur le code.
Après avoir essayé différentes choses, je me suis retrouvé avec une classe de fabrique qui semble rendre les choses si facile.

public class ObjectFactory
{
    private static Dictionary<Type, object> Instances = new Dictionary<Type, object>();

    public static T GetInstance<T>() where T : new()
    {
        if(Instances.ContainsKey(typeof(T)))
            return (T)Instances[typeof(T)];

        return new T();
    }

    public static void SetInstance<T>(object obj)
    {
        Instances[typeof(T)] = obj;
    }
}

Ensuite, sur le code, je peux utiliser

private AreaADBAccess DBAccess = ObjectFactory.GetInstance<AreaADBAccess>();

Et sur la méthode d'essai que je fais quelque chose comme

AreaADBAccess dbAccess = mocks.Stub<AreaADBAccess>();
using (mocks.Record())
{
...
}
ObjectFactory.SetInstance<AreaADBAccess>(dbAccess);
//Invoke the test method
...

Ceci est une première solution et je me rends compte que cela peut être fait d'une meilleure façon.
Pouvez-vous maintenant et me montrer les meilleures pratiques?
Pouvez-vous aussi me expliquer pourquoi je voudrais avoir une interface au lieu de définir les méthodes que virtuel? Il semble inutile de répéter les en-têtes de méthode en 2 endroits.
Merci!

Était-ce utile?

La solution

Probablement, vous pouvez utiliser des conteneurs IoC comme, Windsor, StructureMap ou Ninject, ce qui rendrait votre vie beaucoup plus facile, et en fait, ils travaillent aussi comme « usine » vous avez créé manuellement, mais sont beaucoup plus puissants.

En outre, il y a des conteneurs automocking qui crée automatiquement les dépendances simulacres pour vos classes afin que vous pouvez enregistrer des lignes de code supplémentaires, et de faire votre test moins fragile.

Quant à la question concernant la nécessité d'une interface à la place des classes, son fondamentalement la inversion des dépendances, qui stipule que les modules de niveau supérieur (classes) ne doivent pas dépendre de modules de niveau inférieur (classes), les deux devraient dépendre des abstractions. Les interfaces sont ces abstractions. Je suggère que vous jetez un oeil à des principes S.O.L.I.D qui rendra votre vie beaucoup plus facile, au moins qu'ils ont fait pour moi ..

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top