web-dev-qa-db-ja.com

RSpec共有サンプルにインスタンス変数を渡す方法

RSpec(2.10.1)を使用してモデルの検証をテストしており、他のモデルの検証と共有するコードを抽出しました。検証は最初にCompaniesテーブルに書き込まれたため、コードは次のようになります。

# 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が渡されていないようです(範囲外ですか?)このようなものを機能させるにはどうすればよいですか?

36
George Shaw

問題は、例のグループ内のselfselfフック内のbeforeと異なるため、同じ名前であっても同じインスタンス変数ではないということです。

次のような場合は、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
54
Myron Marston