Frage

Vor einem Monat Ich las das Buch „Art of Unit Testing“ Lesen und heute habe ich es endlich hatte zu beginnen mit Rhino Mocks mit Einheit einen Dienst zu testen, die sendet / empfängt Nachrichten an Geräte (UDP) und speichert / lädt Daten aus der Datenbank.
Off Natürlich will ich die Datenbank und die UDP-Kommunikation isolieren.

Zum Beispiel für den Datenbankzugriff, haben wir einige Klassen mit statischen Methoden, nennen wir sie:

  • AreaADBAccess
  • AreaBDBAccess
  • AreaCDBAccess

hatte Diese Klassen statische Methoden, die den Zugriff auf die Datenbank ausgeführt.
Um der Lage sein, sie Stummel machte ich ihre Methoden public virtual.

Dann begann ich den Code Refactoring der Lage sein, die Instanz dieser Klassen auf dem Code zu ersetzen.
Nachdem verschiedene Dinge versucht, beendete ich mit einem Factory-Klasse auf, die Dinge zu machen, so einfach scheint.

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;
    }
}

Dann auf dem Code, kann ich

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

Und auf der Testmethode ich so etwas wie

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

Dies ist eine erste Lösung, und ich merke, dass es in einer besseren Art und Weise getan werden kann.
Können Sie kommentieren Sie es jetzt und mich zu den besten Praktiken zeigen?
Können Sie mir auch erklären, warum ich eine Schnittstelle stattdessen haben wollen würde die Methoden als virtuelle definieren? Es scheint nutzlos die Methode Header in zwei Orten zu wiederholen.
Dank!

War es hilfreich?

Lösung

Wahrscheinlich könnte man den Einsatz von IoC Container wie, Windsor, StructureMap oder Ninject, machen die Ihr Leben wäre viel einfacher, und in der Tat sie auch Arbeit als „Fabrik“ haben Sie manuell erstellt, sind aber viel leistungsfähiger.

Auch gibt es automocking Behälter, die automatisch mock Abhängigkeiten für Ihre Klassen schaffen, so dass Sie zusätzliche Zeilen Code speichern kann, und machen Sie Ihren Test weniger zerbrechlich.

Wie bei Frage in Bezug auf die Notwendigkeit einer Schnittstelle statt Klassen, seine im Grunde die Abhängigkeit Inversion Prinzip, das besagt, dass höhere Level-Module (Klassen) sollte hängen nicht auf der unteren Ebene Module (Klassen), beide sollten auf Abstraktionen abhängen. Schnittstellen sind diese Abstraktionen. Ich schlage vor, Sie würden einen Blick auf S.O.L.I.D Prinzipien nehmen, die Ihr Leben wird viel einfacher, zumindest sie mir angetan haben ..

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top