Search code examples
ruby-on-railsrspec-rails

Rspec Rails - Stub Active Record Relation to iterate using :find_each


I'm trying to test if a specific attribute some_field gets assigned with correct values. I'm currently not persisting the records on the DB due to speed issues so I need a way thru stubs only.

Here's a sample method:

  class Teacher < ApplicationRecord 
    has_many :students

    def my_method
      ...
      teacher.students.find_each do |s|
        s.some_field[:foo] = 'bar'
        s.save
      end
    end
  end

Here's the test spec which is failing since :find_each only works with ActiveRecord Relations:

it 'assigns a correct value in some_field attribute' do
  allow(teacher).to receive(:students).and_return([student1])
  allow(student1).to receive(:save)

  teacher.my_method
  expect(student1.some_field).to eq({ foo: 'bar' })
end

Error:

NoMethodError:
   undefined method `find_each' for #<Array:0x00007fa08a94b308>

I'm wondering if there's a way for this without persisting in DB?

Any help will be appreciated.


Solution

  • Also mock the find_each and return regular each instead.

    let(:teacher) { double }
    let(:students_mock) { double }
    let(:student1) { double }
    
    it do
      expect(teacher).to receive(:students).and_return(students_mock)
      expect(students_mock).to receive(:find_each) { |&block| [student1].each(&block) }
      expect(student1).to receive(:save)
    
      teacher.students.find_each(&:save)
    end