2009-04-20 7 views
2

Ich habe gerade einen "PluginsService" geschrieben, den ich schreibe. Ich brauche die Systembibliotheken von Assembly, AssemblyName, Directory und File. Zur Zeit erstelle ich Wrapper-Interfaces für jede von diesen, damit ich sie in den Tests verspotten kann. Dies bedeutet jedoch, dass ich einige Wrapper in den Dienst injizieren muss.Unit Testen eines Dienstes mit benötigten Systembibliotheken

So zum Beispiel, wenn eine Methode testen, die einen Ordner für einige Plugins sucht Ich mache diese

With.Mocks(mockery) 
    .Expecting(() => 
    { 
      Expect.Call(directory.GetFiles(PLUGINPATH, PLUGINSEARCHPATTERN)).IgnoreArguments().Return(pluginLibraries); 
      Expect.Call(file.ReadAllBytes(null)).IgnoreArguments().Return(bytes); 
       Expect.Call(assemblyName.GetAssemblyName("fileName")).IgnoreArguments().Return(name); 
      Expect.Call(assembly.GetExecutingAssembly()).Return(executingAssembly); 
    }) 
    .Verify(() => result = service.FindAvailablePlugins()); 

Ich habe 2 Fragen:

  1. Gibt es eine bessere Art und Weise Systembibliothek der Handhabung Artikel für TDD?
  2. Sind 4 zu viele Elemente in eine Klasse zu injizieren?

Antwort

1

Ich habe diese gleiche Sache vor kurzem und kam mit einem Design, wo ich meinen eigenen Directory Gegenstand hatte, die ein DirectoryBoundary hatte, den die Verbindung zu dem Verzeichnis war. Die DirectoryBoundary selbst wurde nicht direkt im Gerät getestet, aber ich habe einige Integrationstests verwendet, um es zu bedecken.

Wenn Sie in diese Richtung gehen, werden Sie feststellen, dass Ihr Design viel flüssiger wird und Ihre Integrationspunkte einfacher sind. Seien wir ehrlich, die .NET-Datei-IO-Klassen wurden nicht für die Testbarkeit entwickelt. Also mach dir deine eigenen Gedanken. Sie können die neuen Directory Klassen spotten, oder tun, was ich getan habe und habe gerade gefälschte Grenzklassen und irgendeine Form eines Schöpfers, den Sie injizieren.

Hoffnung, die hilft.

0

Oren verwendeten so etwas wie dies mit Datetime in Tests umgehen:

public static class SystemTime 
{ 
    public static Func<DateTime> Now =() => DateTime.Now; 
} 

und dann in Tests:

SystemTime.Now =() => new DateTime(2000,1,1); 
repository.ResetFailures(failedMsgs); 
SystemTime.Now =() => new DateTime(2000,1,2); 
var msgs = repository.GetAllReadyMessages(); 
Assert.AreEqual(2, msgs.Length); 

Es ist eine Alternative zur Injektion aber nicht Thread-sicher. Dealing with time in tests

+0

danke ich werde mir das ansehen –

Verwandte Themen