Test di unità di scrittura per una classe che inizia EXE esterno


9

Ho scritto una classe C # che viene utilizzata per avviare un elenco di EXE (non uno dei miei - EXE di terze parti che devo eseguire) e tenerli in esecuzione (controllerà di tanto in tanto per assicurarsi che sia ancora in esecuzione e avviarli in caso contrario) .

Sono in grado di testare la logica di base di aggiunta, rimozione, ecc. Bene. Come posso testare l'unità che funzionerà il vero lavoro di mantenimento degli EXE?

Il mio pensiero iniziale è di avviare un fittizio EXE che si chiude dopo 1 secondo, quindi usarlo per testare. È fuori dal regno del test unitario?

Risposte:


12

Il mio pensiero iniziale è di avviare un fittizio EXE che si chiude dopo 1 secondo, quindi usarlo per testare. È fuori dal regno del test unitario?

È un buon test? Certo, quindi crealo. È "un test unitario" nel vero senso della parola? Non credo, lo definirei un "test di sistema" o qualcosa del genere, ma ciò non rende il test meno prezioso.


9

Deridilo a un livello superiore a quello. Crea una classe proxy Process.Start(), falla finita nel test e controlla l'input.

public interface IProcessProxy
{
     ProcessInfo Start(string application, string[] arguments);
}

public class ProcessProxy : IProcessProxy
{
    public ProcessInfo Start(string application, string[] arguments)
    {
        return Process.Start(application, arguments);
    }
}

// You could use a mocking framework for this, but for the purposes
// of this example ...
public class FakeProcessProxy : IProcessProxy
{
    private string _expectedApplication;
    private string[] _expectedArguments;
    private ProcessInfo response;

    public FakeProxy(string expectedApplication, string[] expectedArguments, ProcessInfo response)
    {
         _expectedApplication = expectedApplication;
         _expectedArguments = expectedArguments;
    }

    public ProcessInfo Start(string application, string[] arguments)
    {
         // compare input to expectations and throw exception if not matching
         return _response;
    }
}

// You can also use an IoC framework to inject your IProcessProxy, but I won't.
public class ClassUnderTest
{
    public ClassUnderTest(IProcessProxy proxy)
    {
        _proxy = proxy;
    }

    public ClassUnderTest() : this(new ProcessProxy())
    {
    }

    public void MethodUnderTest()
    {
        // Do stuff

        ProcessInfo process = _proxy.Start(@"C:\Program Files\App\App.exe", new[] { "arg1", "arg2" });
        process.WaitForExit();

        if (process.ExitCode == 0)
        {
            // Act on success
        }
        else
        {
            // Act on failure
        }
    }   
}

Ovunque sia necessario consumare ClassUnderTest nel codice dell'applicazione, utilizzare il costruttore predefinito. Nei tuoi test, passa un FakeProcessProxy all'altro costruttore, usando i parametri previsti Proxy Start e il risultato del tuo test nel costruttore del falso.


4

Quando rigorosamente seguendo la filosofia di unit testing (enfasi su unità ), non si deve creare un file Exe, ma invece verificare se la classe chiama le interfacce per la deposizione delle uova e monitorare questo processo in modo corretto. Dopotutto, vuoi testare la tua classe, non la libreria responsabile della gestione dei processi.

Ma da un punto di vista pragmatico, il tuo approccio va bene, anche se 1 secondo sembra essere un po 'lungo.


1

Ho fatto qualcosa di simile, ma ho appena chiamato ping localhost. Salva la seccatura di mettere gli eseguibili sul tuo server di build

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.