La risposta breve è "No". La parte più interessante è perché / come potrebbe presentarsi questa situazione.
Penso che la confusione stia sorgendo perché stai cercando di aderire a rigorose pratiche di test (test unitari vs test di integrazione, derisione, ecc.) per codice che non sembra aderire a pratiche rigorose.
Questo non vuol dire che il codice sia "sbagliato" o che determinate pratiche siano migliori di altre. Semplicemente che alcune delle ipotesi formulate dalle pratiche di test potrebbero non essere applicabili in questa situazione e potrebbe aiutare a utilizzare un livello simile di "rigore" nelle pratiche di codifica e nelle pratiche di test; o almeno, per riconoscere che potrebbero essere sbilanciati, il che renderà alcuni aspetti inapplicabili o ridondanti.
La ragione più ovvia è che la tua funzione sta svolgendo due diversi compiti:
- Ricerca di un
Person
in base al loro nome. Ciò richiede test di integrazione, per assicurarci che possa trovare Person
oggetti che sono presumibilmente creati / archiviati altrove.
- Calcolo se
Person
è abbastanza vecchio, in base al sesso. Ciò richiede il test dell'unità, per assicurarsi che il calcolo si comporti come previsto.
Raggruppando queste attività insieme in un blocco di codice, non è possibile eseguirne uno senza l'altro. Quando vuoi testare i calcoli unitari, sei costretto a cercare un Person
(da un vero database o da uno stub / mock). Quando vuoi verificare che la ricerca si integri con il resto del sistema, devi anche eseguire un calcolo sull'età. Cosa dovremmo fare con quel calcolo? Dovremmo ignorarlo o controllarlo? Questa sembra essere la situazione esatta che stai descrivendo nella tua domanda.
Se immaginiamo un'alternativa, potremmo avere il calcolo da solo:
def is_old_enough?(person)
if person.male?
return person.age > 21
else
return person.age > 18
end
end
Poiché si tratta di un calcolo puro, non è necessario eseguire test di integrazione su di esso.
Potremmo anche essere tentati di scrivere separatamente l'attività di ricerca:
def person_from_name(name = 'filip')
return Person::API.new(name)
end
Tuttavia, in questo caso la funzionalità è così vicina a Person::API.new
che direi che dovresti utilizzarla (se il nome predefinito è necessario, sarebbe meglio memorizzarlo altrove, come un attributo di classe?).
Durante la scrittura di test di integrazione per Person::API.new
(o person_from_name
) tutto ciò di cui ti devi preoccupare è se torni indietro del Person
previsto; tutti i calcoli basati sull'età sono presi in considerazione altrove, quindi i test di integrazione possono ignorarli.