Domanda

Sto cercando di scrivere un test C # unità con framework di test VS 2008 di built-in unità e il metodo sto testando le chiamate Environment.Exit(0). Quando chiamo questo metodo nel mio test di unità, il mio test di unità viene interrotta. Il metodo dovrebbe essere in effetti chiamando Exit, e voglio un modo per verificare che lo fa, e anche per testare il codice di uscita che utilizza. Come potrei fare questo? Ho guardato Microsoft.VisualStudio.TestTools.UnitTesting Namespace , ma non ho visto nulla che sembrava rilevante.

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

Nel frattempo, ecco il succo del codice che voglio prova:

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

Modifica ecco la soluzione che ho usato nel mio metodo di prova, grazie 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);
È stato utile?

Soluzione

Questo suona come un incredibilmente cattiva idea. Environment.Exit (0), sarà ovviamente fare come prescritto, quindi, perché i vostri collaudi unità stanno rompendo.

Se davvero si desidera testare ancora questo è possibile con il lancio di un processo separato e controllando il ritorno code-dare un'occhiata a avvolgendolo in Process.Start .

Credo che un'altra opzione è di factoring questo codice fuori e l'iniezione di un prova spia , o utilizzando un oggetto fittizio per verificare il comportamento corretto.

Forse si può fare qualcosa con Typemock Isolator- Credo che questo consente di metodi statici finte .

Altri suggerimenti

È necessario creare un wrapper per la classe Ambiente, quindi utilizzare il wrapper nel codice. Per il test di unità, iniettare una versione finta dell'involucro. L'esempio seguente utilizza RhinoMocks per verificare che il metodo chiama l'involucro con l'argomento previsto.

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

Non sarà in grado di testare questo - Environment.Exit uccide completamente l'applicazione. Questo significa che ogni dominio di applicazione che utilizza questo codice verrà scaricato completamente, sia che si tratti dell'applicazione produzione o il quadro unit testing.

L'unica opzione sarebbe di prendere in giro la classe Ambiente con un metodo fakie Esci.

È possibile aggiungere un argomento per il metodo di passare un ambiente falso in cui il metodo exit () non lo faranno uscire.

È possibile questo metodo parametrizzata estratto dal metodo chiamato dalla vostra applicazione, e l'unità di testare la funzione estratto. In questo modo, non sarà necessario modificare la vostra applicazione.

L'unica cosa che mi viene in mente è qualcosa insieme:

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

static void DoEnvironentExit(int code)
{
    #if defined TEST_SOLUTION
      SomeMockingFunction(code);
    #else
      Environment.Exit(code);
    #endif
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top