Quando test (unità) addFunds
, non dovresti verificare se saveOrUpdate
funziona. Dovresti provare se saveOrUpdate
viene chiamato (nelle giuste circostanze) e lasciarlo.
Se stai andando al test unitario, qualsiasi dipendenza inferiore (come il metodo saveOrUpdate
) dovrebbe essere derisa. Dopo tutto, stai solo provando a testare il metodo addFunds
. Quello che stai suggerendo nella tua domanda è che tu collauda entrambi addFunds
e saveOrUpdate
, il che significa che non hai più unità test.
Non perdere mai traccia di ciò che stai testando .
Ogni volta che vuoi scrivere un test, prima chiediti cosa cerchi di dimostrare con i risultati del test . Se non riesci a pensare a qualcosa di significativo, non dovresti scrivere un test.
Non penso che sia necessario testare questo metodo. Così com'è, tutto ciò che riuscirai a testare sarà se l'orchestrazione dei metodi sottostanti ( getCredits
, setCredits
, saveOrUpdate
) viene chiamata come dovrebbe.
Ma questo test è superfluo. L'orchestrazione dei tre metodi è banalmente leggibile semplicemente guardando il codice. Il metodo non ha percorsi logici divergenti (ad esempio una struttura if else
) che fa sì che il flusso logico sia meno ovvio.
Alcuni controesempi di metodi che giustificano il test:
public void addFunds1(Account account, int price) {
if(!account.IsLocked)
{
int credits = account.getCredits();
account.setCredits(credits + positivePrice);
saveOrUpdate(account);
}
}
Qui c'è un test significativo: il metodo rifiuta correttamente di aggiornare gli account bloccati?
public void addFunds2(Account account, int price, Currency currency) {
if(currency != account.Currency)
{
price = ConvertCurrency(currency, account.Currency, price);
}
int credits = account.getCredits();
account.setCredits(credits + positivePrice);
saveOrUpdate(account);
}
Qui c'è un test significativo: siamo in grado di aggiungere qualsiasi tipo di valuta a un account?
Prendi nota che siamo NON test:
- Se la conversione di valuta è corretta.
- Se il controllo di uguaglianza tra valute è implementato correttamente.
- Se la logica di aggiornamento dell'account funziona.
Cosa testiamo ARE :
- Se il metodo viene convertito nella valuta corretta quando la valuta
price
è diversa dalla valuta account
.
public void addFunds3(Account account, int price) {
bool shouldUpdate = false;
if(!account.IsLocked)
{
shouldUpdate = account.Currency.Code.StartsWith("Z");
}
else
{
int foo = account.AgeInDays + account.getCredits() % 97;
string fooResult = externalRepo.CalculateResult(foo);
shouldUpdate = foo.Length > 3;
}
if(shouldUpdate)
{
int credits = account.getCredits();
account.setCredits(credits + price);
saveOrUpdate(account);
}
}
So che questo è un esempio sciocco, ma è inteso come un esempio di logica complessa e non del tutto ovvia. Ci sono molte cose valide da testare qui. Un'intenzione di test generalizzata potrebbe essere descritta come:
Poiché ci sono motivi per aggiornare l'account solo in determinate situazioni, il metodo aggiorna correttamente l'account in tutte le circostanze necessarie in cui è richiesto un aggiornamento e non aggiorna l'account in tutte le circostanze necessarie in cui un aggiornamento è espressamente proibito? (saranno molti test diversi)