Ricerca…


Osservazioni

Durante il test, a volte è utile utilizzare un test double per manipolare o verificare il comportamento del sistema sottoposto a test. I doppi vengono passati o iniettati nella classe o nel metodo sotto test invece delle istanze del codice di produzione.

Usare uno stub per fornire risposte in scatola

Uno stub è un doppio test leggero che fornisce risposte predefinite quando vengono chiamati i metodi. Quando una classe sottoposta a test si basa su un'interfaccia o una classe base, è possibile implementare una classe "stub" alternativa per il test conforme all'interfaccia.

Quindi, assumendo la seguente interfaccia,

public interface IRecordProvider {
    IEnumerable<Record> GetRecords();
}

Se il seguente metodo doveva essere testato

public bool ProcessRecord(IRecordProvider provider)

Una classe stub che implementa l'interfaccia può essere scritta per restituire i dati noti al metodo in fase di test.

public class RecordProviderStub : IRecordProvider
{
    public IEnumerable<Record> GetRecords()
    {
        return new List<Record> {
            new Record { Id = 1, Flag=false, Value="First" },
            new Record { Id = 2, Flag=true, Value="Second" },
            new Record { Id = 3, Flag=false, Value="Third" }
        };
    }
}

Questa implementazione di stub può quindi essere fornita al sistema in prova, per influenzarne il comportamento.

var stub = new RecordProviderStub();
var processed = sut.ProcessRecord(stub);

Usando una struttura beffarda come uno stub

I termini Mock and Stub possono spesso diventare confusi. Parte della ragione di ciò è che molti framework di simulazione forniscono anche il supporto per la creazione di Stub senza la fase di verifica associata a Mocking.

Piuttosto che scrivere una nuova classe per implementare uno stub come nell'esempio "Uso di uno stub per fornire risposte predefinite", è possibile utilizzare invece i framework di simulazione.

Utilizzando Moq:

var stub = new Mock<IRecordProvider>();
stub.Setup(provider => provider.GetRecords()).Returns(new List<Record> {
    new Record { Id = 1, Flag=false, Value="First" },
    new Record { Id = 2, Flag=true, Value="Second" },
    new Record { Id = 3, Flag=false, Value="Third" }
});

Ciò ottiene lo stesso comportamento dello stub codificato a mano e può essere fornito al sistema sottoposto a test in modo simile:

var processed = sut.ProcessRecord(stub.Object);

Utilizzo di una struttura di simulazione per convalidare il comportamento

I mock sono utilizzati quando è necessario verificare le interazioni tra il sistema in prova e il test raddoppia. Bisogna fare attenzione per evitare di creare test eccessivamente fragili, ma il mocking può essere particolarmente utile quando il metodo da testare è semplicemente quello di orchestrare altre chiamate.

Questo test verifica che quando viene chiamato il metodo in prova ( ProcessRecord ), viene chiamato il metodo di servizio ( UseValue ) per il Record dove Flag==true . Per fare ciò, imposta uno stub con dati in scatola:

var stub = new Mock<IRecordProvider>();
stub.Setup(provider => provider.GetRecords()).Returns(new List<Record> {
    new Record { Id = 1, Flag=false, Value="First" },
    new Record { Id = 2, Flag=true, Value="Second" },
    new Record { Id = 3, Flag=false, Value="Third" }
});

Quindi imposta una simulazione che implementa l'interfaccia di IService :

var mockService = new Mock<IService>();
mockService.Setup(service => service.UseValue(It.IsAny<string>())).Returns(true);

Questi vengono quindi forniti al sistema in prova e viene chiamato il metodo da testare.

var sut = new SystemUnderTest(mockService.Object);

var processed = sut.ProcessRecord(stub.Object);

La simulazione può quindi essere interrogata per verificare che sia stata effettuata la chiamata prevista. In questo caso, una chiamata a UseValue , con un parametro "Second", che è il valore dal record dove Flag==true .

mockService.Verify(service => service.UseValue("Second"));


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow