Le persone sembrano aver spiegato alcuni dei modi fondamentali in cui differiscono, ma tralasciate before(:all)
e non spiegano esattamente perché dovrebbero essere utilizzate.
È mia convinzione che le variabili di istanza non abbiano spazio per essere utilizzate nella stragrande maggioranza delle specifiche, in parte a causa dei motivi menzionati in questa risposta , quindi non le menzionerò come opzione qui.
lascia i blocchi
Codice all'interno di un file let
blocco viene eseguito solo se referenziato, il caricamento lento significa che l'ordinamento di questi blocchi è irrilevante. Questo ti dà una grande quantità di potenza per ridurre la configurazione ripetuta attraverso le tue specifiche.
Un esempio (estremamente piccolo e artificioso) di questo è:
let(:person) { build(:person) }
subject(:result) { Library.calculate_awesome(person, has_moustache) }
context 'with a moustache' do
let(:has_moustache) { true }
its(:awesome?) { should be_true }
end
context 'without a moustache' do
let(:has_moustache) { false }
its(:awesome?) { should be_false }
end
Puoi vedere che has_moustache
è definito in modo diverso in ogni caso, ma non è necessario ripetere la subject
definizione. Qualcosa di importante da notare è che l'ultimolet
blocco definito nel contesto corrente. Questo è utile per impostare un valore predefinito da utilizzare per la maggior parte delle specifiche, che può essere sovrascritto se necessario.
Ad esempio, controllando il valore restituito di calculate_awesome
se passato un person
modello con top_hat
impostato su true, ma senza baffi sarebbe:
context 'without a moustache but with a top hat' do
let(:has_moustache) { false }
let(:person) { build(:person, top_hat: true) }
its(:awesome?) { should be_true }
end
Un'altra cosa da notare sui blocchi let, non dovrebbero essere usati se stai cercando qualcosa che è stato salvato nel database (cioè Library.find_awesome_people(search_criteria)
) poiché non saranno salvati nel database a meno che non siano già stati referenziati. let!
o before
blocchi sono ciò che dovrebbe essere usato qui.
Inoltre, non usare mai e poi maibefore
per attivare l'esecuzione di let
blocchi, ecco cosalet!
è fatto!
permettere! blocchi
let!
i blocchi vengono eseguiti nell'ordine in cui sono definiti (molto simile a un blocco precedente). L'unica differenza fondamentale rispetto ai blocchi precedenti è che ottieni un riferimento esplicito a questa variabile, invece di dover ricorrere alle variabili di istanza.
Come per i let
blocchi, se let!
vengono definiti più blocchi con lo stesso nome, il più recente è quello che verrà utilizzato in esecuzione. La differenza principale è che i let!
blocchi verranno eseguiti più volte se usati in questo modo, mentre il let
blocco verrà eseguito solo l'ultima volta.
prima di (: each) blocchi
before(:each)
è l'impostazione predefinita prima del blocco e pertanto è possibile fare riferimento come before {}
anziché specificare before(:each) {}
ogni volta l'intero .
È mia preferenza personale utilizzare i before
blocchi in alcune situazioni fondamentali. Userò prima dei blocchi se:
- Sto usando la derisione, lo stubbing o il doppio
- Esiste una configurazione di dimensioni ragionevoli (generalmente questo è un segno che i tratti di fabbrica non sono stati impostati correttamente)
- C'è un numero di variabili a cui non ho bisogno di fare riferimento direttamente, ma sono necessarie per l'installazione
- Sto scrivendo test di controller funzionali in rails, e voglio eseguire una richiesta specifica per testare (cioè
before { get :index }
). Anche se potresti usarlo subject
in molti casi, a volte sembra più esplicito se non hai bisogno di un riferimento.
Se ti ritrovi a scrivere before
blocchi di grandi dimensioni per le tue specifiche, controlla le tue fabbriche e assicurati di comprendere appieno i tratti e la loro flessibilità.
prima (: tutti) blocchi
Questi vengono eseguiti solo una volta, prima delle specifiche nel contesto corrente (e dei suoi figli). Questi possono essere usati con grande vantaggio se scritti correttamente, poiché in alcune situazioni ciò può ridurre l'esecuzione e lo sforzo.
Un esempio (che difficilmente influenzerebbe affatto il tempo di esecuzione) è il mock-out di una variabile ENV per un test, che dovresti fare solo una volta.
Spero che aiuti :)