Синтаксис rspec `its` с динамическими условиями - PullRequest
20 голосов
/ 17 октября 2011

Мне очень нравится использовать 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, о котором идет речь.

Ответы [ 3 ]

29 голосов
/ 27 января 2012

Вы почти отвечаете себе, используйте назначение let, прежде чем установить тему.Тогда вы можете ссылаться на него везде:

context "as a user" do
  let(:user) { Factory(:user) }
  subject { user }
  its(:name) { should == user.contact.name }
end

Я тоже context, subject, its любовник!

1 голос
/ 26 октября 2011

Не уверен, есть ли способ сделать именно то, что вы просите, так как «субъект» в блоке становится возвращаемым значением 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, чтобы установить «реальную» связь.

Независимо от выбора, который вы делаете на этих фронтах, эта стратегия хорошо сработала для меня. Я считаю, что это позволяет мне быть более кратким о том, что тестируется, сохраняя при этом информацию (для других разработчиков и будущего себя) о том, откуда берется ожидаемое возвращаемое значение.

0 голосов
/ 30 марта 2012

Вы можете просто установить переменную экземпляра в блоке темы:

context 'as a user' do
  subject { @user = FactoryGirl.create(:user) }

  its(:name) { should == @user.name }
end
...