#28 √ awaiting-patch
Chad Humphries

[#6791] [PATCH] stub return values for all instances of a class

Reported by Chad Humphries | November 19th, 2007 @ 02:58 AM

I'd like to be able to do this:

SomeClass.stub_instance_method!(:method_name).and_return(specified_value)

(syntax just a suggestion)

This should set up a world in which all instances of SomeClass return specified_value for any calls to :method_name.

This differs from SomeClass.stub! in that it applies to instance methods rather

Comments and changes to this ticket

  • Chad Humphries

    Chad Humphries November 19th, 2007 @ 02:58 AM

    Date: 2007-07-18 18:49

    Sender: Carl Porth

    I'd also like to be able to do this:

    SomeClass.new_instances do |instance|

    instance.stub!(:method_name_1).and_return(:value_1)

    instance.stub!(:method_name_2).and_return(:value_2)

    end

    Date: 2007-01-17 20:29

    Sender: Chris Anderson

    Found a solution to my specific problem:

    def login_stub(user)

    controller.stub!(:current_user).and_return(user)

    end

    Just in case someone happens by from a google search etc.

    Date: 2007-01-17 18:24

    Sender: Chris Anderson

    I agree. I'm trying to stub a login_as method for controller

    specs that won't rely on the database. I'd like to have any instance

    of ApplicationController stub :current_user and return my mock

    user. But this doesn't seem possible with the current library.

    Mocha has the feature, so I may lean on it for the time being.

  • David Chelimsky

    David Chelimsky November 19th, 2007 @ 11:53 AM

    • → State changed from “new” to “open”
  • Scott Taylor

    Scott Taylor May 12th, 2008 @ 01:44 AM

    Here's a patch. I've implemented #and_return, #and_raise, and the block feature requested above. Let me know what you think.

  • Scott Taylor

    Scott Taylor May 12th, 2008 @ 01:44 AM

    • → Title changed from “[#6791] stub return values for all instances of a class” to “[#6791] [PATCH] stub return values for all instances of a class”
  • David Chelimsky

    David Chelimsky May 13th, 2008 @ 01:22 PM

    Hey Scott. Thanks for the patch. Very thorough, good specs, etc.

    I do have some concerns however.

    First, I notice that mocha's approach is to add an any_instance method in the chain of calls:

    klass.any_instance.expects(:foo)
    

    You've chosen a single method instead:

    klass.stub_any_instance(:foo)
    

    The problem I see with this approach lies in the fact that it requires duplicating a lot of methods like #and_return and #and_raise. I see that #and_yield is not included, which points out the maintenance problem that this creates.

    This also seems to exclude message expectations (should_receive) - more evidence of the maintenance problem.

    Thoughts?

  • David Chelimsky

    David Chelimsky May 13th, 2008 @ 01:22 PM

    • → Assigned user changed from “” to “David Chelimsky”
  • Scott Taylor

    Scott Taylor May 13th, 2008 @ 05:37 PM

    So you think that putting in a proxy (by method chaining with :any_instance) would allow for more reuse?

    I agree with your concerns. I'll look to refactor this patch, and submit a new one when time permits.

    Thanks again for taking a look.

  • David Chelimsky

    David Chelimsky May 24th, 2008 @ 09:21 PM

    (from [45a68378bf0cde18a5cc3ec64c93388a392f514a]) Add Foo.any_instance.stub!

    Closes LH[#28] (patch from Scott Taylor)

    http://github.com/dchelimsky/rsp...

  • Pat Maddox

    Pat Maddox May 24th, 2008 @ 09:22 PM

    • → State changed from “open” to “resolved”

    Applied in http://github.com/dchelimsky/rsp...

    Thanks a lot for this patch, Scott. Very nice

  • David Chelimsky

    David Chelimsky May 24th, 2008 @ 11:14 PM

    Where did the code from http://github.com/dchelimsky/rsp... come from? It's not what's in the patch attached to this ticket: http://rspec.lighthouseapp.com/a....

    Looks great though :)

  • David Chelimsky

    David Chelimsky May 24th, 2008 @ 11:25 PM

    • → State changed from “resolved” to “open”

    Actually I take that back. This code still has the same problem I mentioned a few comments back. The MethodStubber object duplicates methods in MessageExpectation but does not duplicate all of them. In this case, we're missing and_yield, which leaves MethodStubber feature incomplete in my view.

    I want to see this refactored to reuse functionality from MessageExpectation by either pulling out common functionality or actually using a MessageExpectation object for the proxy.

    I'm going to leave this ticket open until that is resolved.

    Also - I'd like to do a release soon. If this is not resolved by the time I'm ready to release otherwise, I'm going to yank this for the time being. We can always reapply it later.

  • Scott Taylor

    Scott Taylor May 25th, 2008 @ 01:01 AM

    I agree with David - I think the patch should be yanked out, mainly for maintenance reasons. I've been working on a patch which would incorporate the existing functionality already present in the mock/stub library.

    On another note, I have a philosophical testing question: Do "any instance" message expectations support good testing practices (i.e., expectations such as should_receive)? The reason I ask is that this patch was developed to support some legacy code, which IMHO, was not well tested. Stubbing all instances on the class to return a mock was by far the easiest way to get around the bad code.

    Here's my real question: Should rspec support should_receive on an any_instance call?

  • Pat Maddox

    Pat Maddox May 25th, 2008 @ 02:29 AM

    My personal opinion is that any_instance is a crutch. I think it enables you to feel good about having tests, despite the fact that your design is too tightly coupled or has hidden dependencies. I've never once thought to myself that I'd be better off if only I could stub every instance of a class.

    That said, many people disagree with many of my ideas, and I know that stubbing any instance is a feature that a lot of people would find useful. So I think it warrants inclusion in our mocking framework. However, I think it is for stubs only. Setting expectations on every single object in the system of a particular type is absolutely horrendous.

  • Scott Taylor

    Scott Taylor May 25th, 2008 @ 03:16 AM

    I'm pretty much in agreement with you. I can't think of any reason you might want to make an expectation on any_instance.

    I'm going to add and_throw, and_yield support to the patch, reusing the existing code, without adding should_receive support.

    Thanks.

  • Pat Maddox

    Pat Maddox May 25th, 2008 @ 10:23 AM

    Hey, I reverted all the any_instance stuff. I'll keep my nose out of this and let you guys take it from here.

  • David Chelimsky

    David Chelimsky June 23rd, 2008 @ 11:05 AM

    • → State changed from “open” to “awaiting-patch”

    Scott - this still on your radar?

  • Scott Taylor

    Scott Taylor June 23rd, 2008 @ 05:10 PM

    I haven't been working on it recently, as I've gotten very excited by one of my own projects.

    I still have some uncomplete code sitting around in my rspec git repos.

    Why do you ask? Do you want to write it?

  • David Chelimsky

    David Chelimsky June 23rd, 2008 @ 05:20 PM

    Nope. Just trying to clean up the tickets. I put this one on hold

    "awaiting-patch" so it's out of my field of vision :)

    On Jun 23, 2008, at 10:10 AM, Lighthouse wrote:

  • Matt Wynne

    Matt Wynne August 27th, 2008 @ 03:31 PM

    • → Tag changed from “” to “featurerequest mocks patch”

    Just wanted to add my +1 for this feature.

    I don't know whether ActiveRecord counts as 'Legacy Code' but I'm finding it awkward to test AssociationCollection behaviour without hitting the database, and this would really help, I think.

Please Login or create a free account to add a new comment.

You can update this ticket by sending an email to from your email client. (help)

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Behaviour Driven Development for Ruby.

Shared Ticket Bins

Attachments