Я бы добавил еще один случай к тому, что переписал написал
Шпионы дают вам некоторую гибкость.Если вам нужно проверить, что метод был вызван, вы можете сделать это с помощью mocks в before:
before do
expect(foo).to receive(:do_stuff)
end
specify do
bar.run
end
Но before
- не лучшее место для добавления ожиданий.Вы должны разделить этапы настройки, запуска и тестирования .Вы можете сделать это:
specify do
expect(foo).to receive(:do_stuff)
bar.run
end
Но это выглядит лучше, если вы сделаете
before do
bar.run
end
specify do
expect(foo).to have_received(:do_stuff)
end
У вас будет более понятный код, когда есть еще что проверить
before { bar.run }
specify do
expect(foo).to have_received(:do_stuff)
end
context 'with some special conditions' do
before { set_up_special_conditions }
specify do
expect(foo).not_to have_received(:do_stuff)
end
end
Возможно, это не имеет большого значения, и вы все равно можете жить с
specify do
bar.run
expect(foo).to have_received(:do_stuff)
end
context 'with some special conditions' do
before { set_up_special_conditions } # * check the note at the bottom
specify do
bar.run
expect(foo).not_to have_received(:do_stuff)
end
end
Но я думаю, что хороший подход к определению контекстов состоит в том, чтобы явно иметь только существенные различия (set_up_special_conditions
и expect(foo).not_to have_received(:do_stuff)
в примере)упоминается.Все, что не отличается от контекста «выше», не должно появляться в более конкретном контексте «ниже».Это помогает управлять большими спецификациями.
* Примечание: я не уверен насчет порядка блоков before
, определенных таким образом, и после просмотра rspec docs я неуверен, что этот заказ гарантирован.Не могу проверить прямо сейчас.Но только для демонстрационных целей мы можем делать вид, что before { set_up_special_conditions }
будет работать до before { bar.run }
.Но если это не так - есть другие способы обеспечить это, но это выходит за рамки этого вопроса.