[rspec-devel] Fwd: [ rspec-Bugs-6905 ] Mocking rails associations where the association is validated

David Chelimsky dchelimsky at gmail.com
Mon Nov 27 07:45:16 EST 2006


On 11/27/06, Pat Maddox <pergesu at gmail.com> wrote:
> Another question :)
>
> When I first wrote the add_person method, my spec looked like this:
>
>   specify "should accept a new person" do
>     @user.people.size.should_be 0
>     @user.add_person Person.new
>     @user.people.size.should_be 1
>   end
>
> That works, of course, and lets me infer that I have the new user.
> However I think it's ugly that I'm accessing people to verify
> something about the user...
>
> So then I decided to change it to this:
>
>   specify "should accept a new person" do
>     mock_person = mock("person")
>     mock_people = mock("people")
>     @user.should_receive(:people).and_return(mock_people)
>     mock_people.should_receive(:<<).with(mock_person)
>     @user.add_person mock_person
>   end
>
> That feels like the more RSpecy way to do this, despite being longer.
> In both cases they dig into people (either checking the size or
> checking that it calls <<), but in the latter case it verifies
> behavior, rather than inferring it from state.  Does that sound right?

This one is tricky. There are multiple perspectives on how much
mocking you should do in model specs. One view is that model specs are
really small integration specs (model class + database). Another view
is that you should do what you did above, mocking out the other
players where possible.

I'm leaning towards the first view - that model specs are like little
integration specs. My thinking is that because the way AR is designed,
the things you end up mocking are often internal to AR, which is a
huge mocking no-no (mock YOUR code, not other people's).

In this case you could use this to make it feel more RSpecy without
mocking anything:

specify "should accept a new person" do
  lambda do
    @user.add_person
  end.should_change(@user.people.size).by(1)
end

I'm not a huge fan of going after @user.people.size here, but I think
that @user.number_of_people might be overkill.

This is all pretty tricky territory for me. Not nearly as clear as how
to handle the controllers (to me). And, in my view, it boils down to
AR's use of inheritance rather than composition.

Cheers,
David


>
> Pat
> _______________________________________________
> rspec-devel mailing list
> rspec-devel at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-devel
>


More information about the rspec-devel mailing list