Domanda

In una delle mie applicazioni ho una classe che è responsabile per l'input dell'utente. Il metodo predefinito di input è la console (tastiera), e voglio scrivere alcuni test di unità per esso per assicurarsi che sia corretto.

sto valutando con il href="http://code.google.com/p/googletest/" rel="nofollow noreferrer"> google-test quadro

C'è un modo per simulare l'input dell'utente sulla tastiera? O devo inserire manualmente il mio ingresso di test? O forse reindirizzare stdin (sia in codice o da un tubo durante l'esecuzione del test di unità)?

EDIT: Sto pensando di usare GNU readline per l'input dell'utente. Al momento non riesco a vedere alcun modo per reindirizzare il flusso di input di questa biblioteca -? Forse qualcun altro ha esperienza con questo

Altri suggerimenti

In sostanza, la classe deve essere in grado di utilizzare flusso di input casuale, non solo stdin (e si deve refactoring, se è ancora in grado).

Dopo di che sarete in grado di mettere semplicemente un flusso finto con i tuoi dati personalizzati e di simulare qualsiasi input dell'utente.

Mock l'ingresso.

Se la piattaforma è NET, Ecco un modo per farlo .

  

Sto pensando di usare GNU readline   per input dell'utente. Al momento non posso   vedere alcun modo per reindirizzare l'input   flusso di questa libreria

Creare una classe astratta con i membri che corrispondono le funzionalità readline che si desidera utilizzare. Programma contro questa classe astratta anziché direttamente contro l'API readline. Utilizzare iniezione di dipendenza per ottenere un'istanza di questa classe per il codice che ne ha bisogno.

Quindi è possibile creare due implementazioni di questa classe: uno che avvolge semplicemente la libreria readline, e un'altra implementazione finta che è possibile utilizzare per le unit test. L'implementazione mock avrebbe membri extra che lo rendono facile per simulare un utente.

Per .NET / C # è possibile utilizzare la classe di opzioni o varianti si trovano in questa domanda. Perché hai tutti i comandi mappati ai delegati, si può quindi verificare unità ciascuno dei metodi, alla fine dei delegati, e facilmente trovare i comandi sconosciuti:

MyHandler handler = new MyHandler()
CommandOptions options = new CommandOptions();

// Put this in the test Setup
options.Add("show", handler.Show)
        .Add("connect", v => handler.Connect(v))
        .Add("dir", handler.Dir);

if (!options.Parse(args))
   Assert.Fail(string.Format("{0} was not recognised.",args))

La classe MyHandler sarebbe simile a:

public class MyHandler
{
    public void Show() { }
    public void Connect(string[] args){}
    public void Dir() {}
}

Per la console, ho sempre e solo avvolgere con la mia propria implementazione.

Utilizzo di un involucro e l'interfaccia per tutti i controlli 3rd party che sono coinvolti nel test di unità rende il lavoro con una struttura di isolamento (come Rhino Mocks) super facile. Mi dà il controllo su test, ed esplicitamente definisce le dipendenze nel mio codice. Come ho bisogno di nuove funzionalità della console Posso solo aggiungere l'interfaccia involucri. Non ho avuto problemi con l'interfaccia gonfiare ancora ...

public interface IConsoleShim
{
    void WriteLine(string message);
    ConsoleKeyInfo ReadKey();
}
public class ConsoleShim : IConsoleShim
{
    public void WriteLine(string message)
    {
        Console.WriteLine(message);
    }
    public ConsoleKeyInfo ReadKey()
    {
        return Console.ReadKey();
    }
}

Ecco un test in azione

[NUnit.Framework.Test]
public void Run_writes_to_console_100_times_waits_for_keypress()
{
    // arrange
    Rhino.Mocks.MockRepository mocks = new Rhino.Mocks.MockRepository();
    IConsoleShim consoleMock = mocks.StrictMock<IConsoleShim>();
    Program program = new Program(consoleMock);
    int expected = 100;

    // VerifyAll automatically called
    Rhino.Mocks.With.Mocks(mocks).Expecting(() =>
        {
            Rhino.Mocks.Expect.Call(() => consoleMock.WriteLine("")).IgnoreArguments().Repeat.Times(expected);
            Rhino.Mocks.Expect.Call(consoleMock.ReadKey()).Return(new ConsoleKeyInfo());
        });

    //act
    program.Run();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top