2009-07-13 7 views
5

Ich versuche, eine C# Unit-Test mit VS 2008 integrierten Unit-Test-Framework und die Methode, die ich testen Anrufe Environment.Exit(0) schreiben. Wenn ich diese Methode in meinem Komponententest anrufe, wird mein Komponententest abgebrochen. Die Methode sollte in der Tat aufrufen Exit, und ich möchte eine Möglichkeit, das zu testen, und auch den Exit-Code, den es verwendet, zu testen. Wie könnte ich das tun? Ich schaute auf Microsoft.VisualStudio.TestTools.UnitTesting Namespace, aber sah nichts, das relevant erschien.VS2008 Unit-Tests - Assert-Methode Exits

[TestMethod] 
[DeploymentItem("myprog.exe")] 
public void MyProgTest() 
{ 
    // Want to ensure this Exit's with code 0: 
    MyProg_Accessor.myMethod(); 
} 

Inzwischen ist hier der Kern des Code, den ich testen will:

static void myMethod() 
{ 
    Environment.Exit(0); 
} 

Edit: hier ist die Lösung, die ich in meiner Test-Methode verwendet, dank RichardOD:

Process proc; 

try 
{ 
    proc = Process.Start(path, myArgs); 
} 
catch (System.ComponentModel.Win32Exception ex) 
{ 
    proc = null; 
    Assert.Fail(ex.Message); 
} 

Assert.IsNotNull(proc); 
proc.WaitForExit(10000); 
Assert.IsTrue(proc.HasExited); 
Assert.AreEqual(code, proc.ExitCode); 

Antwort

4

Das klingt nach einer unglaublich schlechten Idee. Environment.Exit (0), wird offensichtlich wie vorgeschrieben, also warum Ihre Unit Testings brechen.

Wenn Sie dies wirklich noch testen möchten, können Sie einen separaten Prozess starten und den Rückgabecode überprüfen - sehen Sie sich an, wie Sie es in Process.Start einpacken.

Ich denke, eine andere Möglichkeit ist, diesen Code auszufüllen und eine test spy injizieren, oder ein Mock-Objekt verwenden, um das korrekte Verhalten zu überprüfen.

Vielleicht können Sie etwas mit Typemock Isolator tun- Ich glaube, das lässt Sie mock static methods.

+0

+1 auf TypeMock Trenner hier - es ist die einzige Lösung ist, ich bin mir dessen bewusst, die Sie abfangen können und absolut alles verspotten. –

+0

Die Gefahr, statische Methoden zu verspotten, besteht darin, dass Sie sich nicht davon abhalten lassen, sie so einfach zu benutzen. Ich finde wirklich, dass (für meinen Code) gezwungen wird, extra hart zu arbeiten, um statische Methoden zu haben, ist eine gute Sache, da ich sie nicht verwenden werde, wenn sie nicht die absolut beste Lösung sind. Dies hilft, die Entwicklung mit besseren Techniken, IMO, zu erzwingen. Der Nachteil ist, dass Sie gezwungen sind, durch Ringe zu springen, wenn Sie mit diesen statischen Methoden interagieren, wenn sie sinnvoll sind (oder das Framework ist nicht auf Tests aufgebaut). – tvanfosson

+0

@ tvanfosson- Das ist ein guter Punkt. Deshalb versuchen viele Leute (mich eingeschlossen) zu vermeiden, statische Methoden beim Schreiben von testbarem Code zu verwenden. .NET-Framework-Klassen, die statisch sind, sind ein Pain-Test, und Entwickler müssen oft darauf zurückgreifen, Wrapper-Code zu schreiben, um ihn testbar zu machen (gemäß Ihrer Antwort). Sie können dies aus der Entwicklung von ASP.NET-Webformularen zu ASP.NET MVC sehen. – RichardOD

3

Sie können dies nicht testen - Environment.Exit tötet die Anwendung vollständig. Dies bedeutet, dass jede Anwendungsdomäne, die diesen Code verwendet, vollständig entladen wird, unabhängig davon, ob es sich um Ihre Produktionsanwendung oder das Einheitentestframework handelt.

2

Die einzige Option hier wäre, die Environment-Klasse mit einer fakie Exit-Methode zu verspotten.

5

Sie müssen einen Wrapper für die Klasse Environment erstellen und dann den Wrapper in Ihrem Code verwenden. Für Ihre Komponententests, injizieren Sie eine falsche Version des Wrappers. Im folgenden Beispiel wird mit RhinoMocks überprüft, ob die Methode den Wrapper mit dem erwarteten Argument aufruft.

+1

+1. Nettes Beispiel, wenn ich nicht mein Abendessen essen würde, würde ich etwas in diese Richtung schreiben! Ihr Code erinnert mich an den Standard-Code in ASP.NET MVC-Projekten AccountController-Klasse, was nur eine gute Sache sein kann. Persönlich würde ich die öffentliche EnvironmentWrapper Environment {get; einstellen; } zu einem privaten Set, aber abgesehen von diesem netten Beispiel. – RichardOD

+0

@RichardOD - vereinbart auf dem öffentlichen/privaten. Werde Dich auf dem Laufenden halten. – tvanfosson

0

Sie können Ihrer Methode ein Argument hinzufügen, um eine falsche Umgebung zu übergeben, in der die exit() -Methode nicht beendet wird.

Sie können diese parametrisierte Methode aus der von Ihrer Anwendung aufgerufenen Methode extrahieren und die extrahierte Funktion testen. Auf diese Weise müssen Sie Ihre App nicht ändern.

0

Das einzige, was mir in den Sinn kommt, ist etwas zusammen:

static void myMethod() 
{ 
    DoEnvironmentExit(0); 
} 

static void DoEnvironentExit(int code) 
{ 
    #if defined TEST_SOLUTION 
     SomeMockingFunction(code); 
    #else 
     Environment.Exit(code); 
    #endif 
}