I just read few posts about “how to test named scopes”. It was tons of bullshit.
I am asking – why should I use FactoryGirl or raw models and create a lot of unnecessary stuff (objects, db rows etc.) just to test order(:position).first?!
But first, let’s create Post model. Just an example for this note.
As you see, there are 2 simple scopes. I am not huge fan of Rails’s named scopes – I use plain old class methods instead.
How not to do this
require'spec_helper'describePostdocontext'#recent'doit'should return most recent post'do_,post=[Factory(:post),Factory(:post)]Post.recent.should==postendendcontext'#for_user'doit'should return only posts created by given user'dopost1,post2,_=[Factory(:post,user_id:1),Factory(:post,user_id:1),Factory(:post,user_id:2)]Post.for_user(1).should==[post1,post2]endendend
We’ve just created .. let’s count .. 5 objects and made 2 unnecessary db queries.
How to do this
require'spec_helper'describePostdocontext'#recent'doit'should return most recent post'dopost=mock_modelPostPost.should_receive(:order).with('created_at DESC').and_returnpostpost.should_receive(:first).and_returnpostPost.recentendendcontext'#for_user'doit'should return only posts created by given user'dopost=mock_modelPostPost.should_receive(:where).with(user_id:1)Post.for_user1endendend
I think it’s useless to test Rails’s elements (like where or order). Rails is really proper tested.
Instead we should spec messages between object and passed parameters.