Search code examples
ruby-on-railsrubyrspectddrspec-rails

looping over inside a context in rspec doesn't set the let variable correctly


MY_HASH = {
  user_id: [:email, :first_name],
  email: [:last_name]
}

context "when object's single attribute changed" do
  let(:object) { double("my_object", :changed? => true) }

  before do
    allow(object).to receive("#{attribute}_changed?").and_return(true)
  end

  after do
    allow(object).to receive("#{attribute}_changed?").and_return(false)
  end

  MY_HASH.each do |attr, dependent_attrs|
    let(:attribute) { attr }

    it "should have all dependent attributes in right order for defaulting attribute" do
      expect(subject.send(:my_method)).to eq(dependent_attrs)
    end
  end
end

here attribute is always evaluated to email. I want to iterate over each attribute one by one.

Can anyone help me understand what's going wrong here?

Thanks,


Solution

  • It's because you're redefining attribute each loop:

      MY_HASH.each do |attr, dependent_attrs|
        let(:attribute) { attr }
    

    To fix this, you could introduce a new context/describe block for each iteration:

      MY_HASH.each do |attr, dependent_attrs|
        describe("#{attr}") do
          let(:attribute) { attr }
          it "should have all dependent attributes ..." do
            # content of test here
          end
        end
      end