2017-07-20 1 views
2

Ich habe noch nie Unit-Tests verwendet, aber ich möchte dies vorwärts bewegen. Im Moment habe ich die einfachste Methode, die ich bin zu wollen, um Test:Unit-Test-Bedingungen für Directory.GetFiles

public void GetAvailableFiles(string rootFolder) 
{ 
    string[] dirs = Directory.GetFiles(rootFolder); 
} 

My Unit-Test hierfür ist wie folgt:

[Test] 
public void CheckDirectory() 
{  
    AvailableFile fileUpload = new AvailableFile(); 
    fileUpload.GetAvailableFiles("C:\\Input");  
} 

Wenn ich das Debuggen, kehre ich alle Dateien in meinem Ziel Lage. Ich kämpfe jedoch mit einer gültigen Bedingung, in der dieser Test bestätigen kann, dass er bestanden hat.

Mein Denken war es, eine erwartete Anzahl von Dateien für diesen Test zu haben. Ich habe 10 Dateien drin, also sollte ich 10 Ergebnisse zurück erwarten. Ich bin mir jedoch nicht sicher, wie ich das mit dem, was ich habe, schreiben könnte.

Wie soll ich vorgehen?

+3

Ihr Testaufbau kann (https://stackoverflow.com/a/278457/1269654) [ein temporäres Verzeichnis erstellen], es mit einem Haufen von leeren Dateien mit bekannten Namen füllen, führen Sie Ihre 'GetAvailableFiles' auf dieses Verzeichnis, validieren und bereinigen/entfernen Sie das temporäre Verzeichnis. Das könnte ein bisschen ein künstliches Szenario sein; im Wesentlichen zu testen, dass 'Directory.GetFiles' funktioniert, scheint nicht besonders nützlich zu sein. (Sie geben auch nichts zurück und tun nichts mit dem 'string [] dirs'-Ergebnis, und die Methode ist ungültig. Sie möchten vielleicht, dass sie sie zurückgibt oder die Auflistung der Dateien aufdeckt. Vielleicht ist das nur ein Tippfehler.) –

Antwort

0

Die zu testende Zielmethode ist eng an die statischen Implementierungsfragen gekoppelt (Directory).

So ein Ziel SUT

unter der Annahme
public class AvailableFile { 
    public void GetAvailableFiles(string rootFolder) { 
     string[] files = Directory.GetFiles(rootFolder); 
     //...other code using files 
    } 
} 

Extrakt, der aus in eine explizite Dienstabhängigkeit.

public interface IDirectory { 
    string[] GetFiles(string rootFolder); 
} 

und Umgestalten der SUT

public class AvailableFile { 
    private readonly IDirectory directory; 

    public AvailableFile (IDirectory directory) { 
     this.directory = directory; 
    } 

    public void GetAvailableFiles(string rootFolder) { 
     string[] files = directory.GetFiles(rootFolder); 
     //...other code using files 
    } 
} 

Eine Implementierung des Service in der Produktion wie getan werden kann

public class DirectoryServie { 
    public string[] GetFiles(string rootFolder) { 
     return Directory.GetFiles(rootFolder); 
    } 
} 

Sicherzustellen, dass die Schnittstelle und Implementierung mit Ihren IoC-Containern registriert sind, in Deine Kompositionswurzel.

Nachdem die Entkopplung abgeschlossen ist, können Sie nun Ihre Implementierungen testen, die isoliert von diesen Diensten abhängen. Sie wollen wirklich Code testen, den Sie kontrollieren und nicht 3. Teilimplementierungen, was Directory ist. Microsoft hätte das gut genug getestet.

Mithilfe von Moq können Sie das zu testende Zielsystem isoliert testen, ohne dass eine Verbindung zur Implementierung besteht.

[Test] 
public void CheckDirectory_Should_GetFiles() { 
    //Arrange 
    var files = new [] { 
     "fake path 1", 
     "fake path 2", 
     //fake path n 
    }; 
    var rootPath = "C:\\Input"; 
    var service = new Mock<IDirectory>(); 
    service.Setup(_ => _.GetFiles(rootPath).Returns(files).Verifiable(); 

    var fileUpload = new AvailableFile(service.Object); 

    //Act 
    fileUpload.GetAvailableFiles(rootPath); 

    //Assert 
    service.Verify(); 
} 
6

Es ist kein Komponententest. Es ist ein Integrationstest, weil Sie mit dem Dateisystem interagieren. Wenn Sie einen Komponententest durchführen möchten, müssen Sie die Dateisysteminteraktion auf eine Schnittstelle extrahieren. Zum Beispiel:

public interface IFileScanner { 
    List<string> GetAvailableFiles(string folder); 
} 

[Test] 
public void GetAvailableFiles_EmptyFolder_ReturnsEmptyList() 
{  
    // Arrange 
    IFileScanner scanner = new FileScannerEmptyFolderStub(); 

    // Act 
    var list = scanner.GetAvailableFiles("dummy argument"); 

    // Assert 
    Assert.IsTrue(list.Count == 0); 
} 

Ich schlage vor, Sie einige Theorie in Buch zu lesen The art of unit testing with examples (Roy Osherove), bevor Sie Unit-Tests schreiben können.

+0

Ich löschte meinen letzten Kommentar, da ich dachte, ich hätte ihn, aber ich bin mir nicht sicher, was mit der ersten Zeile "FileScannerEmptyFolderStub()" – N0xus

+1

@ N0xus Ich denke, es ist zu komplex Thema hier zu diskutieren. Sehen Sie das Buch, das ich Ihnen in meiner Antwort vorschlage. Im Moment können Sie folgen Chris Sinclair Kommentar zu bewegen – opewix

+1

Ich würde auch vorschlagen, in "Spott" zu sehen. –

0

Geben Sie die Methode einige temporäre Verzeichnis mit einigen Dateien darin:

public class TestClass : IDisposable 
{ 
    private string _directory; 

    public TestClass() 
    { 
     _directory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); 
     Directory.CreateDirectory(_directory); 
    } 

    [Fact] 
    public void NoFiles() 
    { 
     Assert.Empty(GetAvailableFiles(_directory)); 
    } 

    [Fact] 
    public void TwoFiles() 
    { 
     File.WriteAllText(Path.Combine(_directory, "aaa.txt"), ""); 
     File.WriteAllText(Path.Combine(_directory, "bbb.txt"), ""); 

     var files = GetAvailableFiles(_directory); 
     Assert.Equal(2, files.Length); 
     Assert.Contains(Path.Combine(_directory, "aaa.txt"), files); 
     Assert.Contains(Path.Combine(_directory, "bbb.txt"), files); 
    } 

    public void Dispose() 
    { 
     Directory.Delete(_directory, true); 
    } 

    // Method under test 
    public string[] GetAvailableFiles(string rootFolder) 
    { 
     return Directory.GetFiles(rootFolder); 
    } 
} 

Dieser Test ist schnell und benötigt keine Abhängigkeiten und so während es nicht unbedingt ein Unit-Test ist es nicht der Fall ist mit vielen der Nachteile, die normalerweise mit Integrationstests verbunden sind (die auf externe Datenbanken angewiesen sind, usw.)

Wenn diese Methode eine beträchtliche Menge anderer Logik enthält (zB mit dem Inhalt dieser Dateien arbeiten), dann ist es ein gutes Idee, eine Nahtstelle zwischen dieser Logik und dem Dateisystemzugriff einzuführen.

Verwandte Themen