Quando la proprietà è definita nel database di produzione (o un clone per il test), questo non è un test di unità . Un test unitario controlla un'unità di lavoro e non richiede un particolare stato esterno per funzionare. Ciò presuppone che Offer1
sia definita nel database come un'offerta di soli uomini. Questo è lo stato esterno. Quindi questo è più di un test di integrazione , in particolare un sistema o accettazione . Nota che i test di accettazione spesso non sono script (non vengono eseguiti in un framework di test ma eseguiti manualmente da esseri umani).
Quando la proprietà viene definita nel modello di dominio con un'istruzione if
, lo stesso test è un test unitario. E potrebbe essere fragile Ma il vero problema è che il codice è fragile. Come regola generale, il codice sarà più resiliente se il comportamento aziendale è configurabile anziché codificato. Perché una distribuzione rapida per risolvere un piccolo errore di codifica dovrebbe essere rara. Ma un requisito aziendale che cambia senza preavviso è solo un martedì (qualcosa che succede settimanalmente).
È possibile che si stia utilizzando un framework di test unitario per eseguire il test. Ma i framework per le unit test non sono limitati ai test unitari in esecuzione. Possono anche eseguire test di integrazione.
Se stavi scrivendo un test unitario, creerai sia person
che offer1
da zero senza fare affidamento sullo stato del database. Qualcosa come
[Fact]
public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale()
{
var personId = Guid.NewGuid();
var gender = "F";
var person = new Person(personId, gender);
var id = Guid.NewGuid();
var offer1 = new Offer1(id, "ReturnsFalseWhenGivenAPersonWithAGenderOfFemale");
offer1.markLimitedToGender("M");
Assert.False(offer1.IsEligible(person));
}
Si noti che questo non cambia in base alla logica aziendale. Non sta asserendo che offer1
rifiuta le femmine. Sta facendo offer1
del tipo di offerta che respinge le donne.
È possibile creare e configurare il database come parte del test. In C #, usando NUnit, o in JUnit di Java, devi impostare il database in un metodo Setup
. Presumibilmente la tua struttura di test ha una nozione simile. In tale metodo, è possibile inserire record nel database con SQL.
Se è difficile per te scrivere codice che sostituisce un database di test per il database di produzione, sembra una debolezza di test nella tua applicazione. Per il test, sarebbe meglio usare qualcosa come l'iniezione di dipendenza che consente la sostituzione. Quindi è possibile scrivere test che sono indipendenti dalle attuali regole aziendali.
Un vantaggio collaterale di questo è che è spesso più semplice per il proprietario dell'azienda (non necessariamente il proprietario dell'azienda, più come la persona responsabile di questo prodotto nella gerarchia aziendale) per configurare direttamente le regole aziendali. Perché se si dispone di questo tipo di framework tecnico, è facile consentire al proprietario dell'azienda di utilizzare un'interfaccia utente (UI) per configurare l'offerta. Il proprietario dell'attività commerciale selezionerebbe la limitazione nell'interfaccia utente e emetterebbe la chiamata markLimitedToGender("M")
. Quindi, quando l'offerta viene mantenuta nel database, la memorizzerebbe. Ma non avresti bisogno di archiviare l'offerta per usarla. Quindi i tuoi test potrebbero creare e configurare un'offerta che non esiste nel database.
Nel tuo sistema come descritto, il proprietario dell'azienda dovrebbe inserire una richiesta al gruppo tecnico, che emetterebbe l'SQL appropriato e aggiornerà i test. Oppure il gruppo tecnico deve modificare il codice e i test (o testare il codice). Sembra un approccio piuttosto pesante. Puoi farlo. Ma il tuo software (non solo i tuoi test) sarebbe meno fragile se non dovessi farlo.
TL; DR : puoi scrivere test come questo, ma potresti stare meglio scrivendo il tuo software in modo da non doverlo fare.