Testing - concise derisioni contro l'affermazione di chiamate ricevute

0

Diciamo che abbiamo questo metodo:

string Add(int a, int b) {
    var sum = _calculator.Add(a,b);
    var response = _formatter.Format(sum);
    return response;
}

Ora voglio testare unitamente questo metodo. Supponiamo ovviamente che il codice non sia in realtà banale, _calculator e _formatter potrebbero essere servizi esterni, c'è qualche logica nel metodo stesso, e voglio essere sicuro di chiamare tutte le mie dipendenze correttamente e restituire il risultato corretto. Ovviamente _calculator e _formatter verranno derisi, ma cosa dovrei prendere in giro e cosa dovrei verificare? Vedo anche le opzioni -

Imposta i mock per rispondere a qualsiasi input con output specifico e successivamente assicurati che siano stati chiamati con l'input previsto:

calculator = Substitute.For<ICalculator>();
calculator.Add(Arg.Any<int>(), Arg.Any<int>()).returns(123);
formatter = Substitute.For<IFormatter>();
formatter.Format(Arg.Any<int>()).returns("yup");

var subject = new DidntThinkOfClassName(calculator, formatter);
var res = subject.Add(1, 2);

calculator.Received(1).Add(1, 2);
formatter.Received(1).Format(123);
res.ShouldBe("yup");

O configura i mock in SOLO rispondendo all'input previsto, quindi verifica solo il risultato finale:

calculator = Substitute.For<ICalculator>();
calculator.Add(1, 2).returns(123);
formatter = Substitute.For<IFormatter>();
formatter.Format(123).returns("yup");

var subject = new DidntThinkOfClassName(calculator, formatter);
var res = subject.Add(1, 2);

res.ShouldBe("yup");

Nella prima opzione accetto qualsiasi input, ovvero mock più semplici, ma devo verificare le chiamate ricevute. Nella seconda opzione sistemo i miei mock in modo tale che il risultato finale possa essere raggiunto solo se ogni singolo finto ha ricevuto esattamente ciò che è stato configurato per ricevere, quindi ho solo bisogno di controllare il risultato finale.

Cosa diresti è meglio? C'è una soluzione migliore che mi manca?

    
posta Ridiculous 04.12.2018 - 19:45
fonte

1 risposta

2

Now I want to unit-test this method. Assume of course the code is not actually that trivial, _calculator and _formatter might be external services, there's some logic in the method itself, and I want to make sure I'm calling all of my dependencies correctly and return the correct result. Of course _calculator and _formatter will be mocked, but what should I mock and what should I verify?

Ci sono un paio di discorsi che ti aiuteranno a capire la tua domanda.

In breve: quando si introducono i duplicati di prova, si esegue il white box dei progetti di test. In particolare, presti attenzione a come vengono utilizzate le dipendenze.

Se le chiamate al tuo test raddoppia sono query, quindi non ti preoccupare affatto dei messaggi in uscita. Basta inserire una doppia di prova con la risposta corretta codificata in esso e testare il comportamento del soggetto.

(Elencato per primo, perché il codice che hai scritto suggerisce che Calculator :: Add e Formatter :: Format sono query. Vedi Query di comando separazione ).

Se si suppone che le chiamate alle dipendenze abbiano effetti collaterali sulle dipendenze stesse, allora si potrebbe avere un test che deride la dipendenza per verificare che gli argomenti corretti siano passati al metodo corretto.

I’d have loved to see her dig down a bit more on interactions which are commands and queries at the same time. How do you handle this case ?

Prova i due pezzi separatamente. Scrivi un test che esercita il soggetto del test e conferma che ha inviato i messaggi corretti; scrivi un test separato che esercita il soggetto del test e conferma che il risultato è soddisfacente.

    
risposta data 05.12.2018 - 03:36
fonte

Leggi altre domande sui tag