简体   繁体   中英

How to deal with stubbing new method with potential Nil class in Ruby and rspec

I have a situation where I stub the .new method of a class, but that makes it to return nil objects, and later those objects are needed, and I am not sure how to deal with it. Here is my rspec code:

describe ShopWorker do
  describe '#perform' do
    let(:worker) { ShopWorker.new }
    it 'creates a new instance of Shopper' do
      user = FactoryGirl.create(:user)
      expect(Shopper).to receive(:new).with(user)
      worker.perform(user.id)
    end
  end
end

And here is my Worker code:

class ShopWorker
  include Sidekiq::Worker

  def perform(user_id)
    user = User.find(user_id)

    shopper = Shopper.new(user)
    shopper.start # This fails because Shopper.new returns NIL
  end
end

So, since I am stubbing the new method with expect(Shopper).to receive(:new).with(user) , then when in the worker it does shopper.start, that is nil, and therefore it breaks. How should I solve this? Ideally, I would like to test that a new instance of Shopper is done and also that the method start is called for that instance.

There are a couple of things you can do:

  1. Expect to receive :new but provide a return value (possibly a mock), using and_return() . The problem is that to receive has an implicit and_return(nil) unless you provide a return value explicitly.
  2. Don't stub :new , let it do its job and expect :start on any Shopper instance: expect_any_instance_of(Shopper).to receive(:start) .
  3. Ask yourself what value this test provides. The test knows a lot about the implementation, to a point where you always have to change both. What is the impact of shopper.start ? Can you assert anything about the actual business value?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM