Search code examples
rspecrspec-rails

How to set an RSpec expectation for an object that doesn't exist yet


How would I test that a message is sent to MyCoolClass when a record is created?

describe MyModel, type: :model do
  it 'should call this class' do
    # how do I set the expectation of new_record_id?
    expect_any_instance_of(MyCoolClass).to receive(:a_method).with(new_record_id, :created)
    MyModel.create
  end
end

The only alternative is this:

describe MyModel, type: :model do
  it 'should call this class' do
    new_record = MyModel.new
    expect_any_instance_of(MyCoolClass).to receive(:a_method).with(new_record, :created)
    new_record.save
  end
end

The problem here, though is that I'm testing save, not create, which is mostly ok for my case. But the bigger problem is that it means I have to change the implementation of MyCoolClass to be passed a record, instead of the id.


Solution

  • I see two variants

    1) use anything or kind_of(Numeric)

    it 'should call this class' do
      expect_any_instance_of(MyCoolClass).to receive(:a_method).with(kind_of(Numeric), :created)
      MyModel.create
    end
    

    2) Stub save or create method and return double

    let(:my_model) { double(id: 123, save: true, ...) }
    
    it 'should call this class' do
      MyModel.stub(:new).and_return(my_model)
      expect_any_instance_of(MyCoolClass).to receive(:a_method).with(my_model.id, :created)
      MyModel.create
    end