Pergunta

Eu estou tentando escrever um C # teste de unidade com o VS 2008 do built-in framework de testes unitários e o método que eu estou testando chamadas Environment.Exit(0). Quando eu chamar esse método no meu teste de unidade, o meu teste de unidade é abortada. O método deve realmente ser chamado Exit, e eu quero uma maneira de teste que ele faz, e também para testar o código de saída que ele usa. Como eu poderia fazer isso? Olhei para Microsoft.VisualStudio.TestTools.UnitTesting Namespace , mas não viu nada que parecesse relevante.

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

Enquanto isso, aqui está a essência do código que eu quero de teste:

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

Editar: aqui está a solução que eu usei no meu método de teste, graças a 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);
Foi útil?

Solução

Isso soa como uma incrivelmente má idéia. Environment.Exit (0), irá, obviamente, fazer como prescrito, daí porque seus testes unitários estão quebrando.

Se você realmente quer ainda testar isso, você pode com o lançamento de um processo separado e verificando o retorno Código- ter um olhar para envolvê-lo em Process.Start .

Eu acho que outra opção é factoring este código para fora e injetando um teste espião , ou usando um objeto de simulação para verificar o comportamento correto.

Talvez você possa fazer algo com Typemock Isolator- Eu acredito que este permite que você métodos estáticos simulados .

Outras dicas

Você vai precisar para criar um wrapper para a classe Environment, em seguida, utilizar o wrapper em seu código. Para os testes de unidade, injetar uma versão simulada do wrapper. O exemplo a seguir usa RhinoMocks para verificar se o método chama o wrapper com o argumento esperado.

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()
}

Você não será capaz de testar isso - Environment.Exit mata a aplicação completamente. Isto significa que qualquer AppDomain que utiliza este código irá ser descarregado completamente, se é o seu aplicativo de produção ou o framework de testes unitários.

Sua única opção aqui seria zombar a classe ambiente com um método fakie Sair.

Você pode adicionar um argumento para o seu método de passá-lo um ambiente falso onde o método exit () não vai sair.

Você pode este método parametrizada extraído do método chamado a partir da aplicação e teste de unidade a função extraído. Dessa forma, você não terá que modificar seu aplicativo.

A única coisa que vem à minha mente é algo ao longo:

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

static void DoEnvironentExit(int code)
{
    #if defined TEST_SOLUTION
      SomeMockingFunction(code);
    #else
      Environment.Exit(code);
    #endif
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top