Модульные тесты VS2008 - метод assert завершается - PullRequest
5 голосов
/ 13 июля 2009

Я пытаюсь написать модульное тестирование на C # с помощью встроенного в VS 2008 фреймворка модульного тестирования, и метод, который я тестирую, вызывает Environment.Exit(0). Когда я вызываю этот метод в моем модульном тесте, мой модульный тест прерывается. Метод должен действительно вызывать Exit, и я хочу проверить способ его выполнения, а также проверить код завершения, который он использует. Как я могу это сделать? Я посмотрел на Microsoft.VisualStudio.TestTools.UnitTesting Namespace , но не увидел ничего, что выглядело соответствующим.

[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);

Ответы [ 6 ]

5 голосов
/ 13 июля 2009

Вам нужно создать оболочку для класса 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()
}
4 голосов
/ 13 июля 2009

Это звучит как невероятно плохая идея. Environment.Exit (0), очевидно, будет работать в соответствии с предписаниями, поэтому ваши тестовые модули не работают.

Если вы действительно хотите по-прежнему проверять это, вы можете, запустив отдельный процесс и проверив код возврата, взгляните на его завершение в Process.Start .

Я полагаю, что другой вариант - выделить этот код и добавить тестового шпиона или использовать фиктивный объект для проверки правильности поведения.

Возможно, вы можете что-то сделать с помощью Typemock Isolator - я считаю, что это позволяет вам макетировать статические методы .

3 голосов
/ 13 июля 2009

Вы не сможете проверить это - Environment.Exit полностью убивает приложение. Это означает, что любой AppDomain, использующий этот код, будет выгружен полностью, будь то ваше производственное приложение или среда модульного тестирования.

2 голосов
/ 13 июля 2009

Ваша единственная возможность здесь - это смоделировать класс Environment с помощью метода fakie Exit.

0 голосов
/ 13 июля 2009

Единственное, что приходит мне в голову - это что-то не так:

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

static void DoEnvironentExit(int code)
{
    #if defined TEST_SOLUTION
      SomeMockingFunction(code);
    #else
      Environment.Exit(code);
    #endif
}
0 голосов
/ 13 июля 2009

Вы можете добавить аргумент в ваш метод, чтобы передать ему ложную среду, в которой метод exit () не завершится.

Вы можете этот параметризованный метод извлечь из метода, вызванного из вашего приложения, и выполнить модульное тестирование извлеченной функции. Таким образом, вам не придется изменять приложение.

...