2010-02-19 8 views
6

Ich mag Ausgang erfassen, um die Standardausgabe und Standardfehler innerhalb eines MSTest Unit-Tests geschickt, damit ich es überprüfen kann. Ich habe die Ausgabe vor dem expliziten Ausführen einer Process erfasst, aber gibt es eine Möglichkeit, mit [ich denke] der MSTest-Prozess selbst zu tun? Zum Beispiel:Kontrollausgang in MSTest Unit-Test

[TestMethod] 
public void OutputTest() 
{ 
    MySnazzyMethod("input", 1, 'c'); 
    string stdOutFromMySnazzyMethod = /* ??? */; 
    Assert.AreEqual("expected output", stdOutFromMySnazzyMethod); 
} 

Antwort

3

mochte ich JaredPar's idea aber ich wollte nicht in Console.Out und Console.Error jeden Helfer Ausgang Methode zu übergeben. Allerdings ist mein Ausgang über eine einzige Klasse gehen, so dass ich setze nur ein paar statische Felder in ihm:

internal static TextWriter _stdOut = Console.Out; 
internal static TextWriter _stdErr = Console.Error; 

ich meine Ausgabemethoden in der Ausgabe-Handler-Klasse aktualisiert, um die Verwendung dieser Felder zu machen. Ich habe dann aktualisiert, dass Projekt AssemblyInfo.cs enthält:

[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyTestProject")] 

Auf diese Weise, ich _stdOut und _stdErr in meinen Testmethoden außer Kraft setzen kann, rufen Sie meine Methode getestet werden (was meine Ausgabe Handling-Klasse verwendet), und bestätigen Sie die Ausgabe habe ich erwartet.

OutputHandler._stdOut = new StringWriter(); 
MySnazzyMethod("input", 1, 'c'); 
OutputHandler._stdOut.Flush(); 
string expected = "expected output"; 
string stdout = OutputHandler._stdOut.ToString().Trim(new[] { '\r', '\n' }); 
Assert.IsFalse(string.IsNullOrEmpty(stdout)); 
Assert.AreEqual(expected, stdout); 
+0

Seien Sie mit statischen Feldern in Testklassen vorsichtig. Stellen Sie sicher, dass Sie OutputHandler._stdOut und/oder OutputHandler._stdErr zu Beginn jedes Tests, der sie verwendet, festlegen, wenn Sie sie verwenden werden. MSTest Unit-Test-Suiten (nicht bestellt Tests) in einer nichtdeterministische Art und Weise ausgeführt werden, so dass spätere Tests in Ihrem Laufe haben diese Felder nicht richtig eingestellt zu Console.Out und Console.Error, bevor sie versuchen, diese TextWriters zu verwenden. (TestInitialize() und TestCleanup() garantieren auch keine Sicherheit.) – David

0

Fügen Sie einfach ein paar TraceListener in der Klasse initialize Ihre Testklassen.

3

Ich bin nicht sicher, ob es eine Möglichkeit ist, die Ausgabe eines bereits laufenden Process zu greifen. Was Sie tun können, ist wenn Ihr Code Refactoring leicht nicht zu Console.WriteLine schreiben, sondern in einem TextWriter Beispiel nehmen und schreiben, dass.

In der Produktion können Sie dann Console.Out an die Methode übergeben einfach. Im Testcode könnten Sie diesen Typ vortäuschen und viel genauere Tests liefern. Ich hatte zum Beispiel

[TestMethod] 
public void OutputTest() 
{ 
    var writer = new Mock<TextWriter>(MockBehavior.Strict); 
    writer.Setup(x => x.WriteLine("expected output")).Verifiable(); 
    MySnazzyMethod(writer.Object, "input", 1, 'c'); 
    writer.Verify(); 
} 

Produktionscode

MySnazzyMethod(Console.Out, "input", 1, 'c'); 
0

ich Moles verwenden würde, um den Anruf zu Console schreibt an eine Lambda-Methode in Ihrem Testcode zu umleiten.

string result = ""; 
System.Moles.MConsole.WriteLineString = (s) => 
    { result = s; }; 
Assert.IsTrue(result == "The string I want", 
    "Failed to write to console correctly"); 

Siehe Seite 16 in diesem Dokument: Moles Reference Manual.