rspec-mocks icon indicating copy to clipboard operation
rspec-mocks copied to clipboard

[Feature] General stubbing with `.should_receive(anything)` or `double.as_null_object(:default_return)`

Open leandro opened this issue 9 years ago • 2 comments

The idea is to be able to mock or stub irrelevant objects (to the given test case concerns) one wants to simply bypass in oneself code logic. So, if one has an object obj that is referenced multiple times in the logic with multiple different method calls, one would like to bypass those calls and return any specific value for them instead getting instances like #<RSpec::Mocks::Double:0x3fe22cd3dd50 @name=nil> when double.as_null_object is used.

So, some solution ideas to solve this need would be:

  • double.as_null_object(1) -- it'd return 1 as the value for any method called upon such mocked object.
  • object.should_receive(anything) { 1 } -- any (existing) called method for the given object would be stubbed and returned 1 for it.
  • allow(object).to receive(anything) { 1 } -- equivalent to previous approach

Furthermore, it'd be nice to add exceptions to the general stubbing like:

mocked_obj = double.ass_null_object(1)
mocked_obj.should_receive(:specific_method) { 3 }

This way, you'd still be able to specify exceptions to the default returned value. I'm not sure if we already have a solution for that in RSpec, but if not, I'd like to ask you for a solution in this sense.

leandro avatar Oct 26 '15 13:10 leandro

double.as_null_object(1) -- it'd return 1 as the value for any method called upon such mocked object.

I think we could do something like this (although I'd probably make the API as_null_object(returning: 1)).

allow(object).to receive(anything) { 1 }/object.should_receive(anything) { 1 } is hard to do performantly (they'd have to iterate over all methods defined on the object and stub each individually, which is going to be relatively slow) and, IMO, don't really make sense, anyway. If you want to stub everything on a test double, that's what as_null_object is for. If you've got a partial test double (where as_null_object can't be used), I don't think it makes sense to stub everything -- once you stub everything the original behavior of the partial double no longer remains, so why not use a real test double?

Do you want to take a stab at adding a :returning option to as_null_object?

myronmarston avatar Oct 26 '15 15:10 myronmarston

Sounds fair. I'll give it a try (by sending a PR).

Thanks.

leandro avatar Oct 26 '15 17:10 leandro

Closing due to inactivity during the monorepo migration, but if someone wanted to revisit this they'd be welcome.

JonRowe avatar Nov 27 '24 20:11 JonRowe