[rspec-users] Stubs and Object Constructor

David Chelimsky dchelimsky at gmail.com
Wed Mar 23 06:34:24 EDT 2011


On Mar 20, 2011, at 11:38 PM, andyl wrote:

> OK - I got this working using mocha and the 'any_instance' method.  
> 
> A gist with working examples is here: https://gist.github.com/879029
> 
> It looks like rspec mocks had an 'any_instance' method, but it was removed because it promoted 'bad practice'.

It was never released, and was removed because the patch was incomplete in retrospect. There is an open issue on this right now, with a patch in progress that I hope to include in the next release, assuming it is ready when that release is ready to go.

> I'm curious to understand how 'any_instance' promotes bad practice.  I found it useful in my situation, to stub out slow network code that crushed my test performance.

In general, we want test code to be as narrow and precise as possible. This means we should control which objects we are dealing with at any moment. any_instance is a bandaid for a situation in which the design makes it difficult to get a handle on a specific instance. If we're actually doing TDD this should never happen, but sometimes we use frameworks like ActiveRecord, which provides two different objects in this scenario:

widget = Factory(:widget)
found_widget = Widget.find(widget.id)

These two objects ^^ have the same attributes, but are not the same object. This means that stubbing methods on widget does not have any impact on found_widget. In this case, any_instance saves the day, but it leaves open some holes in tests. Consider:

order = Factory(:order)
Order.any_instance.should_receive(:confirm)
put :confirm, :order_id => order.id

If the examples and code change over time such that there are more than one order at play and the wrong one receives confirm(), this example will still pass.

FYI - ActiveRecord will soon have an identity map, which means that this code will work:

order = Factory(:order)
order.should_receive(:confirm)
put :confirm, :order_id => order.id

This is a much better situation as it is very precise.

HTH,
David



More information about the rspec-users mailing list