Подтвердить что ты не робот

Синтаксис 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 вопросу.

4b9b3361

Ответ 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