Blog

Nov
18
RSpec Mocking Association Collections
by Shane Mingins | Snippet

I can’t recall where I saw this example now, but it saves me a line of code and in specs, that’s important.

I often used to do the following when mocking model association collections:


projects = mock("Array of Projects")
mock_user.stub!(:projects).and_return(projects)
projects.should_receive(:find).with("1")

But with a little Ruby magic you can do this instead:

mock_user.stub!(:projects).and_return(projects = mock("Array of Projects"))
projects.should_receive(:find).with("1")

Which I think reduces a bit of noise.

Another tip I just discovered for stubs is this:


mock_user.stub!(:update_attributes => false)

instead of


mock_user.stub!(:update_attributes).and_return(false)

Again, just minor, but it makes it look cleaner.

Comments?

3 Comments
Peer Allan
November 19, 2008

Being tests I would go for the more verbose and more descriptive definitions. It may be a bit more typing, but since tests can be very useful in understanding the logic in the code the more descriptive it can be, the better. I am a big fan of time saving shortcuts as long as they are used consistently. Once you start mixing, long and short forms is when things can get more confusing.

Shane Mingins
November 21, 2008

@peer I prefer my tests to be short and to the point, so as long as terse code is readable and understandable I am happy. Looking at my first example I have actually used mock_user.should_receive when in fact I should use a stub as the test is in fact testing the find method on the projects object and not the user.products association. I am going to edit this post to reflect that.

macaco
December 23, 2008

oh my god it works