[rspec-users] stub_model() and ActiveRecord Associations

David Chelimsky dchelimsky at gmail.com
Tue Aug 26 20:01:18 EDT 2008

On Tue, Aug 26, 2008 at 1:34 PM, Matt Wynne <matt at mattwynne.net> wrote:
> Hi all,
> I have what I thought was quite a simple requirement but something to do
> with the way ActiveRecord's associations work is making it quite puzzling.
> I guess I can sum it up with this failing test:
>         before(:each) do
>           @source_comment = @source.comments.create(:user_id => 1)
>           @target_comment = @target.comments.create(:user_id => 1)
>         end
>         it "should return the same object from create() as from the array"
> do
>           (@target_comment.equal?(@target.comments[0])).should be_true
>           do_merge
>         end
> What I actually want to be able to do, is mock a method call on the
> @target_comment but I'm finding that I get unreliable results:
>           @target.comments[0].should_receive(:merge_in) # works
> #          @target_comment.should_receive(:merge_in) # doesn't work
> The code I'm testing is using self.comments.each() to access the object it's
> going to call merge_in() on - the one I want to mock.
> Any tips here folks?
> Someone here has suggested that what I really need to do is express my mock
> like... (commence pseudo code)
> Comment.should_receive_instance_method(:merge_in).with(...).on_an_object_matching{|o|
> o.id = @target_comment.id}
> (/pseudo code)
> Has anyone else come across similar issues? How did you approach them?

Here's the basic deal:

=> false

AR does not cache objects, so when you ask it for what you *think*
might the same object twice, you get different ones.

mocha offers an 'any_instance' method, which gives you basically what
you are describing with should_receive_instance_method, but rspec does
not yet have a counterpart in its mocking library.

I can tell you how I handle this, but let me say that this is a less
than perfect way to handle a less than perfect situation so it's
difficult for me to say "this is a recommended approach." That said

@target_comment = stub_model(Target)


> cheers,
> Matt

More information about the rspec-users mailing list