2012-07-06 139 views
35

我正在使用RSpec(2.10.1)在模型上測試驗證並提取了一些代碼以與其他模型驗證共享。該驗證首次寫在公司的表,所以代碼如下所示:如何將實例變量傳遞給RSpec共享示例

# 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沒有被傳遞(不在範圍內?)我如何得到這樣的東西來工作?

回答

49

問題是self示例組中的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 
+1

一些碎片不會道理給我。如果這是'自我'是不同的,它在哪裏不同?爲什麼在'shared_examples'中'@ company.send()'和'@ company.should'工作?在你的建議中,我可以用'@ company'替換'Company.new()'(保留'之前'塊)並且工作正常。我的理解是缺少一些關於這裏究竟發生了什麼的事情。看起來,「自我」在一個特定的地方(「it_behaves_like」直到「do」)纔有所不同。 – 2012-07-06 17:02:09

+6

RSpec中有兩個基本值'self',它類似於ruby類定義中的self的兩個值。在'describe' /'context' /'shared_examples_for'和它相應的'end'(但不在'it'塊)之間,'self'就是例子組 - 就像類體中的'self'一樣不在方法定義中)是類本身。 ''''''''''''''''''''''''或''''''''''''後面的''''self'就是例子 - 就像類的實例方法定義中的'self'是類的實例。 – 2012-07-12 05:24:08

+3

另一種思考方式:RSpec執行一個雙通過程。首先,它將評估所有嵌套的'describe' /'context' /'shared_examples_for'塊,以便定義所有示例;在這一點上,這些環境中的「自我」就是相應的例子組。其次,RSpec運行所有定義的例子('it'塊)。每個定義的示例都在相應示例組的實例中進行評估,'self'就是示例。 – 2012-07-12 05:27:23