Синтаксис rspec `its` с динамическими условиями
Мне очень нравилось использовать contexts
, subjects
и its
с помощью rspec для действительно очистки моего тестового кода. Типичный пример:
context "as a user" do
subject{ Factory :user }
its(:name){ should == "Bob" }
end
То, что я не могу понять, это то, как я могу сделать это условие динамическим (т.е. основанным на других объектах). its
появляется экземпляр eval атрибута внутри блока, поэтому я теряю доступ ко всему вокруг него. Я хотел бы сделать что-то вроде:
its(:name){ should == subject.contact.name }
Но я не вижу никакого способа добиться этого. Кто-нибудь знает, есть ли какой-либо метод, проксированный через этот экземпляр eval, который дает доступ к исходному объекту? Или, если есть какой-либо другой способ, я могу использовать методы вне области экземпляра атрибута, который я проверяю?
дополнительная информация
Кажется, что subject
в блоке its
изменяется на фактический атрибут (name
в этом случае)
Интересно, что у меня есть доступ к любому из моих методов let
, но опять же, у меня нет доступа к исходному subject
вопросу.
Ответы
Ответ 1
Вы почти отвечаете на себя, используйте назначение let
, прежде чем устанавливать тему. Затем вы можете ссылаться на него повсюду:
context "as a user" do
let(:user) { Factory(:user) }
subject { user }
its(:name) { should == user.contact.name }
end
Я тоже context
, subject
, its
любовник!
Ответ 2
Не уверен, есть ли способ сделать то, что вы просите, поскольку "субъект" внутри блока становится возвращаемым значением User#name
.
Вместо этого я использовал метод let
вместе со следующим стилем спецификации, чтобы написать этот тип теста:
describe User do
describe '#name' do
let(:contact) { Factory(:contact, name: 'Bob') }
let(:user) { Factory(:user, contact: contact) }
subject { user.name }
it { should == 'Bob' }
end
end
Это, конечно, делает некоторые предположения о том, что представляет ваш контакт (здесь это ассоциация или подобное). Вы также можете отключить возвращаемое значение User#contact
вместо того, чтобы полагаться на FactoryGirl для создания "реальной" ассоциации.
Независимо от выбора, который вы делаете на этих фронтах, эта стратегия сработала для меня. Я нахожу, что это позволяет мне быть более кратким из-за того, что тестируется, сохраняя при этом информацию (для других разработчиков и будущего) о том, откуда ожидается ожидаемое возвращаемое значение.
Ответ 3
Вы можете просто установить переменную экземпляра в блоке темы:
context 'as a user' do
subject { @user = FactoryGirl.create(:user) }
its(:name) { should == @user.name }
end