Ma question est à peu près expliquée par le titre. J'essayais de le rechercher sur Google, mais je n'ai rien trouvé de satisfaisant. rubocop-rspec ne permet pas expect
à l'intérieur avant
, pourquoi est-ce? Y a-t-il une bonne raison d'éviter un tel usage? Merci pour vos explications à l'avance!
3 Réponses :
Seuls les tests doivent inclure des attentes (également appelées assertions). Les blocs before
sont destinés à configurer l'environnement dans lequel vos tests s'exécutent. Ils ne sont pas censés être des tests eux-mêmes.
Le
Le test en quatre phases est un modèle de test couramment utilisé pour les tests unitaires. C'est la forme générale:
RSpec.describe User do describe '#forgot_password' do before { allow(EmailService).to receive(:send) } subject { FactoryBot.create(:user).forgot_password } it 'sends an email to user to start the password resetting process' do subject expect(EmailService).to have_received(:send).with(...) end end end
avant
fait partie de la phase setup
où le développeur crée le scénario et les données de support.
expect
fait partie de la phase verify
, qui se déroule à l'intérieur d'un bloc it
.
Un modèle courant consiste à utiliser allow
dans les blocs before
et à utiliser expect
dans les blocs it
par exemple. P > Des blocs
test do setup exercise verify teardown end
avant
peuvent également être ajoutés dans d'autres couches de l'application ( spec_helper.rb
, exemples partagés) et on ne le fait pas voulez vous fier à l'ordre correct des blocs avant pour qu'un test réussisse.
Je suis d'accord avec les attentes des filtres avant
puisque vous ne changez rien dans les exemples, vous testez toujours la configuration générale, mais dans les filtres après
je ne vois pas une raison pour éviter les attentes.
Lors de l'écriture de tests, le contexte est ce qui compte le plus, vous testez le même code sous différents paramètres (ou contextes), par conséquent, les exemples n'ont qu'à modifier le contexte et l'assertion pourrait rester constante.
Voir cet exemple:
RSpec.describe Foo do subject { create(:foo) } describe 'some_method' do let(:foo) { create(:foo) } it 'gives higher rates to foos with more reviews if all are positive' do foo.update!(votes_up_count: 10, reviews_count: 10) subject.update!(votes_up_count: 1, reviews_count: 1) foo.update_rate subject.update_rate expect(foo.rate).to be > subject.rate end it 'gives higher rates to foos with less positive reviews and no negative reviews' do foo.update!(votes_up_count: 4, reviews_count: 4) subject.update!(votes_up_count: 5, reviews_count: 6) foo.update_rate subject.update_rate expect(foo.rate).to be > subject.rate end end end
Par opposition à
RSpec.describe Foo do subject { create(:foo) } describe 'some_method' do let(:foo) { create(:foo) } after do foo.update_rate subject.update_rate expect(foo.rate).to be > subject.rate end it 'gives higher rates to foos with more reviews if all are positive' do foo.update!(votes_up_count: 10, reviews_count: 10) subject.update!(votes_up_count: 1, reviews_count: 1) end it 'gives higher rates to foos with less positive reviews and no negative reviews' do foo.update!(votes_up_count: 4, reviews_count: 4) subject.update!(votes_up_count: 5, reviews_count: 6) end end end
Donc je ne prendrais pas ceci flic comme évangile pour être honnête, je pense que cela va à l'encontre des bonnes pratiques de test.