5

我正在尝试使用 VS 2008 的内置单元测试框架和我正在测试的方法调用 C# 单元测试Environment.Exit(0)。当我在单元测试中调用此方法时,我的单元测试已中止。该方法确实应该调用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);
4

6 回答 6

5

您需要为 Environment 类创建一个包装器,然后在代码中使用该包装器。对于您的单元测试,注入包装器的模拟版本。以下示例使用 RhinoMocks 来验证该方法是否使用预期的参数调用包装器。

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<EnvironmentWrapper>();

     int expectedCode = 5;

     mockWrapper.Expect( m => m.Exit( expectedCode ) );

     var myClass = new MyClass( mockWrapper );

     myclass.MyMethod( expectedCode );

     mockWrapper.VerifyAllExpectations()
}
于 2009-07-13T19:54:00.503 回答
4

这听起来像是一个非常糟糕的主意。Environment.Exit(0),显然会按照规定执行,因此您的单元测试会中断。

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

我想另一种选择是将这段代码分解出来并注入一个测试间谍,或者使用一个模拟对象来验证正确的行为。

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

于 2009-07-13T19:48:52.340 回答
3

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

于 2009-07-13T19:48:09.657 回答
2

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

于 2009-07-13T19:50:05.457 回答
0

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

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

于 2009-07-13T19:54:26.150 回答
0

我唯一想到的是:

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

static void DoEnvironentExit(int code)
{
    #if defined TEST_SOLUTION
      SomeMockingFunction(code);
    #else
      Environment.Exit(code);
    #endif
}
于 2009-07-13T19:57:07.957 回答