Стандарт кодирования, который я работаю, указывает, что группа спецификаций, проверяющих функцию, должна иметь объект, который является вызываемой функцией. Это выглядит следующим образом:Выполняет ли rspec блок `subject`?
define User do
context :foo do
let(:user) { FactoryGirl.create(:user) }
subject { user.foo }
it { ... }
end
end
Типичное использование subject
блока для создания экземпляра класса, который вы проверяете:
define User do
subject { FactoryGirl.create(:user) }
it { ... }
end
планируемый эффект нашего руководства стиля является то, что у нас другая тема блок для каждого тестируемого метода. Это замедляет наши тесты? Если бы мы использовали subject
в типичной манере, могли бы мы извлечь выгоду из встроенной мемуаризации или других ускорений только из одного предметного блока для каждого класса?
Asside:
Я столкнулся один случай, когда наш стиль не работает. При использовании any_instance.should_receive
вы не можете следовать нашему руководству по стилю или спецификация всегда терпит неудачу. Вместо этого вам нужно использовать более традиционный подход, где subject
- объект, который вы тестируете, и вы вызываете метод на нем в вашей спецификации.
# passing spec
define Foo do
before { Bar.any_instance.stub(:baz) }
subject { FactoryGirl.create(:foo) }
it "bazzes Bars" do
Bar.any_instance.should_receive(:baz)
subject.baz_the_bars
end
end
# spec follows style guide but fails
define Foo do
before { Bar.any_instance.stub(:baz) }
let(:foo) { FactoryGirl.create(:foo) }
subject { foo.baz_the_bars }
it "bazzes Bars" do
Bar.any_instance.should_receive(:baz)
subject
end
end
class Foo
has_many :bars
def baz_the_bars
bars.collect do |bar|
bar.baz
end.count(true)
end
end
Есть ли какой-либо другой вопрос, который я должен искать в этом стиле?
Возможно, у меня что-то не хватает, почему ваш стук Бар вызывает проблемы? Субъект еще не вызывается, поэтому утверждение все равно должно быть установлено до запуска метода. – Shepmaster
В блоке 'before' я не забиваю' Bar'. Я улаживаю метод 'baz()', в любом экземпляре 'Bar'. Мой первый проход был: 'before {Bar.stub (: baz)}', который также работал. Но это не прошло обзора кода, поэтому мне нужно было изменить блок 'before'. – user2574255
Извините, я не был понятен - я имел в виду укусить 'baz' на всех« барах ». Тем не менее, я все еще не понимаю, почему ваш тест терпит неудачу. Не могли бы вы обновить свой пример для запуска? 'define' не является допустимым ключевым словом здесь, и я думаю, вы можете отказаться от ссылок на ActiveModel и FactoryGirl. Возможно, это поставит вопрос и на более ответственный вопрос. – Shepmaster