2012-07-06 95 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