VS2008unit testing – 断言方法退出

我正在尝试使用VS 2008的内置unit testing框架编写C#unit testing,我正在测试的方法是调用Environment.Exit(0) 。 当我在unit testing中调用此方法时,我的unit testing被中止。 该方法确实应该调用Exit ,我想要一种方法来测试它,并且还要测试它使用的退出代码。 我怎么能这样做? 我查看了Microsoft.VisualStudio.TestTools.UnitTesting命名空间,但没有看到任何看起来相关的内容。

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

同时,这是我要测试的代码的要点:

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

编辑:这是我在测试方法中使用的解决方案,感谢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); 

这听起来像是一个非常糟糕的主意。 Environment.Exit(0),显然会按照规定进行,因此你的unit testing会破坏。

如果你真的想要测试它,你可以通过启动一个单独的进程并检查返回代码 – 看看它在Process.Start中包装它。

我想另一个选择是将此代码分解并注入测试间谍 ,或使用模拟对象来validation正确的行为。

也许你可以用Typemock Isolator做点什么 – 我相信这可以让你模拟静态方法 。

您需要为Environment类创建一个包装器,然后在代码中使用包装器。 对于您的unit testing,请注入包装器的模拟版本。 以下示例使用RhinoMocksvalidation该方法是否使用expected参数调用包装器。

 public class EnvironmentWrapper { public virtual void Exit( int code ) { Environment.Exit( code ); } } public class MyClass { private EnvironmentWrapper Environment { get; set; } public MyClass() : this( null ) { } public MyClass( EnvironmentWrapper wrapper ) { this.Environment = wrapper ?? new EnvironmentWrapper(); } public void MyMethod( int code ) { this.Environment.Exit( code ) } } [TestMethod] public void MyMethodTest() { var mockWrapper = MockRepository.GenerateMock(); int expectedCode = 5; mockWrapper.Expect( m => m.Exit( expectedCode ) ); var myClass = new MyClass( mockWrapper ); myclass.MyMethod( expectedCode ); mockWrapper.VerifyAllExpectations() } 

您将无法对此进行测试 – Environment.Exit完全杀死该应用程序。 这意味着任何使用此代码的AppDomain都将被完全卸载,无论是您的生产应用程序还是unit testing框架。

这里你唯一的选择是使用fakie Exit方法模拟Environment类。

您可以向方法添加一个参数,以将其传递给exit()方法不会退出的虚假环境。

您可以从应用程序调用的方法中提取此参数化方法,并对提取的函数进行unit testing。 这样,您就不必修改您的应用。

我唯一想到的是:

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