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

Как передать переменную экземпляра в общий пример RSpec

Я использую RSpec (2.10.1) для проверки валидности на модели и извлек некоторый код для совместного использования с другими проверками модели. Проверки были сначала записаны в таблице компаний, поэтому код выглядит следующим образом:

# support/shared_examples.rb
shared_examples "a text field" do |field, fill, length|
  it "it should be long enough" do
    @company.send("#{field}=", fill * length)
    @company.should be_valid
  end

  etc...
end

а использование:

# company_spec.rb
describe Company do
  before { @company = Company.new( init stuff here ) }

  describe "when address2" do
    it_behaves_like "a text field", "address2", "a", Company.address2.limit
  end

  etc...
end

Я хотел бы передать @company в качестве параметра в общий пример, чтобы я мог повторно использовать код для разных моделей, примерно так:

# support/shared_examples.rb
shared_examples "a text field" do |model, field, fill, length|
  it "it should be long enough" do
    model.send("#{field}=", fill * length)
    model.should be_valid
  end

  etc...
end

а использование:

# company_spec.rb
describe Company do
  before { @company = Company.new( init stuff here ) }

  describe "when address2" do
    it_behaves_like "a text field", @company, "address2", "a", Company.address2.limit
  end

  etc...
end

Однако, когда я это делаю, я получаю undefined method 'address2' for nil:NilClass. Похоже, что @company не передается (не в области?) Как мне заставить что-то подобное работать?

4b9b3361

Ответ 1

Проблема заключается в том, что self в группе примеров отличается от self внутри before hook, поэтому она не является той же переменной экземпляра, даже если она имеет то же имя.

Я рекомендую использовать let для таких случаев:

# support/shared_examples.rb
shared_examples "a text field" do |field, fill, length|
  it "it should be long enough" do
    model.send("#{field}=", fill * length)
    model.should be_valid
  end
end

# company_spec.rb
describe Company do
  describe "when address2" do
    it_behaves_like "a text field", "address2", "a", Company.address2.limit do
      let(:model) { Company.new( init stuff here ) }
    end
  end
end