Вопрос

Я пытаюсь написать модульный тест C # с помощью встроенной платформы модульного тестирования VS 2008 и метода, который я тестирую, вызывает Environment.Exit(0).Когда я вызываю этот метод в своем модульном тестировании, мой модульный тест прерывается.Метод действительно должен вызывать Exit, и мне нужен способ проверить, что он делает, а также протестировать код выхода, который он использует.Как я мог бы это сделать?Я посмотрел на Microsoft.VisualStudio.Средства тестирования.Пространство имен 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);
}

Редактировать: вот решение, которое я использовал в своем методе тестирования, благодаря Ричардод:

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), очевидно, будет работать так, как предписано, отсюда и причина сбоев в ваших модульных тестированиях.

Если вы действительно хотите все еще протестировать это, вы можете, запустив отдельный процесс и проверив код возврата - посмотрите, как обернуть его в Процесс.Начать.

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

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

Другие советы

Вам нужно будет создать оболочку для класса 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()
}

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

Вашим единственным вариантом здесь было бы издеваться над классом среды с помощью поддельного метода Exit .

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

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

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

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

static void DoEnvironentExit(int code)
{
    #if defined TEST_SOLUTION
      SomeMockingFunction(code);
    #else
      Environment.Exit(code);
    #endif
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top