Is There a Less Intrusive Alternative to Rspec's 'Should_Receive'

Is there a less intrusive alternative to Rspec's `should_receive`?

It looks like the nicer API to delegate to the original method that Myron Marston alluded to has actually been added in rspec-mocks v2.12.0

  • Add and_call_original which delegates to the original method.

So now you can simply do this any time you "want to set a message expecation without interfering with how the object responds to the message":

@baker.should_receive(:make_batter).and_call_original

Thanks for adding this, Myron.

How do I deal with rspec should_receive replacing the method when I want the method to actually be executed?

You deal with this by adding .and_call_original to your method chain as follows:

UserMailer.should_receive(:new_order).with(order).and_call_original

as documented in https://www.relishapp.com/rspec/rspec-mocks/v/2-13/docs/message-expectations/calling-the-original-method and discussed in Is there a less intrusive alternative to Rspec's `should_receive`?

rspec's should_receive on a non-mock object?

Your line here:

@image.should_receive(:duplicate!).once

Is working with only that specific @image instance, and calling should_receive only on it so that expectation doesn't transfer over to the image objects used inside the duplicate method (or any other place where an image is instantiated) even if it is the same record from the database.

Is receive(:method).never completely equivalent to not_to receive(:method)

As per this link https://github.com/rspec/rspec-mocks/issues/895
You can use either of these to cause an example to fail if a method is called
Author @myronmarston also provided an example

Is there a way to make RSPec's error messages be more insightful?

Test frameworks generally permit you to assert that an actual result is equal to an expected result, and when that assertion fails, will print out the assertion as well as the expected and actual results.

There's not much more they can do. What you seem to be looking for is magical intuition on the part of software.

Try something like:

response.status_code.should == 200

This compares the actual status_code with the expected status_code, asserting their equality, and printing both if the assertion fails.

Why is this Ruby conditional assignment not memoized?

The issue is this line:

UserPresenter.should_receive(:new).once

This chunk of code simply sets up the expectation that a UserPresenter will receive the new method one time. It tears down your original UserPresenter#new method and replaces it with a method that returns nil. Because nil is falsy, the @presenter instance variable is not memoized.

To fix this, you can specify a return value in your expectation:

UserPresenter.should_receive(:new).once.and_return "some truthy value"

or equivalently

UserPresenter.should_receive(:new).once { "some truthy value" }

or if you absolutely want to call the original method

UserPresenter.should_receive(:new).once.and_call_original

or with the new expect syntax

expect(UserPresenter).to receive(:new).once.and_call_original

See this for more information about expecting a message, and this for more information about calling the original method. This has some further discussion about RSpec's should_receive method.

Why is this Ruby conditional assignment not memoized?

The issue is this line:

UserPresenter.should_receive(:new).once

This chunk of code simply sets up the expectation that a UserPresenter will receive the new method one time. It tears down your original UserPresenter#new method and replaces it with a method that returns nil. Because nil is falsy, the @presenter instance variable is not memoized.

To fix this, you can specify a return value in your expectation:

UserPresenter.should_receive(:new).once.and_return "some truthy value"

or equivalently

UserPresenter.should_receive(:new).once { "some truthy value" }

or if you absolutely want to call the original method

UserPresenter.should_receive(:new).once.and_call_original

or with the new expect syntax

expect(UserPresenter).to receive(:new).once.and_call_original

See this for more information about expecting a message, and this for more information about calling the original method. This has some further discussion about RSpec's should_receive method.



Related Topics



Leave a reply



Submit