rspec @variable返回nil

时间:2019-03-03 03:06:25

标签: ruby-on-rails rspec-rails ruby-on-rails-5.2

我的@attributes变量有问题。我希望可以访问它以保持代码干燥,但是目前,我必须重新声明该变量并将其设置为“ values”才能使rspec测试正常工作。在没有重复值的情况下执行此操作的更好方法是什么。

ref:Unexpected nil variable in RSpec

表明在describe中不可访问,但是需要另一种解决方案。什么时候“指定”合适?我没有用过。

describe "When one field is missing invalid " do 
    before(:each) do 
        @user = create(:user)
        @attributes = {"has_car"=>"true", "has_truck"=>"true", "has_boat"=>"true", "color"=>"blue value", "size"=>"large value"}
    end
  values = {"has_car"=>"true", "has_truck"=>"true", "has_boat"=>"true", "color"=>"blue value", "size"=>"large value"}
  values.keys.each do |f|
    p = values.except(f) 
    it "returns invalid when #{f.to_s} is missing" do 
              cr = CarRegistration::Vehicle.new(@user, p)
        cr.valid?
    end
  end
end

根据评论更新: 我还想在其他测试中使用values数组哈希。如果我按照说明将其放入循环中,我仍然必须在其他地方重复该过程。还有其他建议吗?

更新:我尝试使用let()

  describe "When one field is missing" do

        let(:user) {Factorybot.create(:user)}
        let(:attributes) = {{"has_car"=>"true", "has_truck"=>"true", "has_boat"=>"true", "color"=>"blue value", "size"=>"large value"}}

      attributes do |f|
        p = attributes.except(f) 
        it "returns invalid when #{f.to_s} is missing" do 
                  cr = CarRegistration::Vehicle.new(user, p)
            cr.valid?
        end
      end
  end

但出现以下错误。

attributes在示例组(例如describecontext块)上不可用。仅在单个示例内(例如it块)或在示例范围内运行的构造(例如beforelet等)中可用。

3 个答案:

答案 0 :(得分:1)

在您的两个摘要中,您都不需要attributes 内部。它是生成规范的数据。因此,它必须位于上一级。

describe "When one field is missing" do

  let(:user) { Factorybot.create(:user) }

  attributes = { "has_car" => "true", "has_truck" => "true", "has_boat" => "true", "color" => "blue value", "size" => "large value" }

  attributes do |f|
    p = attributes.except(f)
    it "returns invalid when #{f.to_s} is missing" do
      cr = CarRegistration::Vehicle.new(user, p)
      cr.valid?
    end
  end
end

答案 1 :(得分:0)

您似乎已经认识到,基于链接到的其他SO帖子,您无法在describe块中引用实例变量。只需将其设置为局部变量即可。

答案 2 :(得分:0)

使用let

describe "When one field is missing" do
  let(:user) {Factorybot.create(:user)}
  let(:attributes) = {{"has_car"=>"true", "has_truck"=>"true", "has_boat"=>"true", "color"=>"blue value", "size"=>"large value"}}
  ## The variables are used INSIDE the it block.
  it "returns invalid when a key is missing" do
    attributes do |f|
      p = attributes.except(f)
      cr = CarRegistration::Vehicle.new(user, p)
      expect(cr.valid?).to eq(true)  # are you testing the expectation? Added this line.    
    end
  end
end

我个人不喜欢编写由于多种原因而失败的测试(如上述)。塞尔吉奥是正确的。但是,如果要使用let,则必须在it块的WITHIN中使用它-此示例显示了这一点。