Object.any_instance should_receive vs expect() to receive

The following piece of code works as expected:

Object.any_instance.should_receive(:subscribe)

But when using the new rspec expectation it does not work:

expect(Object.any_instance).to receive(:subscribe)

The error is:

expected: 1 time with any arguments
received: 0 times with any arguments

How can I make this work with expect() to receive?

32907 次浏览

There's now a not very well documented method called expect_any_instance_of that handles the any_instance special case. You should use:

expect_any_instance_of(Object).to receive(:subscribe)

Google expect_any_instance_of for more info.

Just a heads up, expect_any_instance_of is now considered deprecated behaviour according to Jon Rowe (key rspec contributor). The suggested alternative is to use the instance_double method to create a mock instance of your class and expect calls to that instance double, as described in that link.

Jon's method is preferred (since it can be used as a generalized test helper method). However if you find that confusing, hopefully this implementation for your example case can help make sense of the intended method:

mock_object = instance_double(Object) # create mock instance
allow(MyModule::MyClass).to receive(:new).and_return(mock_object) # always return this mock instance when constructor is invoked


expect(mock_object).to receive(:subscribe)

Good luck! 🙏🏽