每当前迭代在多个示例中重用变量

时间:2018-05-04 23:05:37

标签: ruby-on-rails ruby rspec

我有一个有点贵的变量。我希望将它重用于每个集合的多个示例,如下所示:

describe MyModel, type: :model do
  describe ".seed" do
    before(:example) do
      described_class.seed
    end

    %w{field_1 field_2 field_3 field_4}.each do |field|
      let(:dynamic_field) { described_class.find_by_code('Car').dynamic_fields.values.detect {|item| item['field'].eql?(field) } }

      it "contains #{field}" do
        expect(dynamic_field).to include( "field" => field )
      end

      it "contains :field_type" do
        expect(dynamic_field).to include "field_type_id"
      end
   end
  end
end

因此,当field == 'field_1'时,应声明let,并将其用于两个示例。当field_2是当前迭代时,应重新声明let。不幸的是,一旦let定义一次,它在整个示例中保持相同的值。

我尝试使用before(:example) { @dynamic_field = ... },但这也只是在第一次迭代时声明。

那么我应该如何在每个当前数组迭代的多个示例中重用变量?

2 个答案:

答案 0 :(得分:0)

所以let和before(:example)只会被赋值一次。从某种意义上说,它们是被记忆的。因此,为了不写重复代码,我创建了一个帮助器。

在rails_helper.rb中:

require 'support/my_helpers'
RSpec.configure do |config|
  config.include MyHelpers
end

然后在support / my_helpers.rb中:

module MyHelpers
  def get_dynamic_data(type, field)
     ....
  end
end

这不是记忆。因此,对于每个数组迭代,我都能够获得一个新值,同时也不会编写重复的代码。

答案 1 :(得分:0)

由于let的整个点是在示例之间记忆值,我建议仅使用它来存储集合并将动态变量本身拉到示例块。

let(:dynamic_fields) do
  described_class.find_by_code('Car').dynamic_fields.values
end

%w{field_1 field_2 field_3 field_4}.each do |field|
  it "contains #{field} and :field_type", :aggregate_failures do
    dynamic_field = dynamic_fields.detect {|item| item['field'].eql?(field) }

    expect(dynamic_field).to include( "field" => field )
    expect(dynamic_field).to include "field_type_id"
  end
end

使用:aggregate_failures对您的示例进行分组,但仍会针对每个期望获得单独的失败消息。

https://relishapp.com/rspec/rspec-core/docs/expectation-framework-integration/aggregating-failures