[rspec-users] Stub named_scope with params

Zach Dennis zach.dennis at gmail.com
Thu Nov 5 17:30:47 EST 2009


On Thu, Nov 5, 2009 at 5:10 PM, Elza Di Sirio
<elza.morelli at tagview.com.br> wrote:
> I need some help to stub this method of my controller
>  @users =
>         User.accessible_by(current_user).paginate(
>           :conditions => conditions.to_sql,
>           :include    => :user_channels,
>           :order      => build_sort_conditions(:name, true),
>           :page       => get_param(:page, :integer),
>           :per_page   => 10
>         )
>   end
> My rspec is
>   describe 'GET /index' do
>     ##############################################################
>     should_require_login :get, :index
>     ##############################################################
>     describe "authenticated user" do
>       ##############################################################
>       before do
>         login_as_user
>         check_session_expiration
>         @user = mock_model(User)
>         @users = [@user]
>         User.stub_chain(:accessible_by, :paginate).and_return(@users)
>
>
>
>       end
>
>
>
>       ##############################################################
>       it 'should load the users' do
>         User.should_receive(:paginate).with(
>           :conditions => ['active = ?', true],
>           :order => :name,
>           :page => nil,
>           :per_page => 10
>         ).and_return(@users)
>         do_get
>
>
>
>         assigns[:users].should == @users
>       end
>     end
>   end
> ##############################################################
> The error I get is
> Spec::Mocks::MockExpectationError in 'UsersController GET /index
> authenticated user should load the users'
> <User(id: integer, name: string, email: string, crypted_password: string,
> password_salt: string, persistence_token: string, role: string, active:
> boolean, password_last_changed_at: datetime, created_at: datetime,
> updated_at: datetime)
> (class)> expected :paginate with ({:per_page=>10, :conditions=>["active =
> ?", true], :order=>:name, :page=>nil}) once, but received it 0 times
> ./spec/controllers/users_controller_spec.rb:269:
> *************************************************
> How should I stub a named_scope with params(accessible_by(current_user)),
> following a stub to paginate.with(...).


In your example User does not receive the #paginate call, the return
value of #accessible_by does. It looks like you're having both of
those methods return @users in your spec by default. Try updating your
spec to say...

   @users.should_receive(:paginate)...

instead of

   User.should_receive(:paginate)...

> I can not change my controller

In case you can change your controller... this controller action seems
pretty vanilla. I would probably add some good model-level specs
around #accessible_by, and then have a few cucumber scenarios ensure
whatever it was that pulled up this page was working (I like scenarios
for pagination as well). To make things easier I would assign the
default PER_PAGE to a configuration setting or a constant so it can be
easily changed in a scenario. This can reduce scenario running time
and necessary setup whilst still ensuring behaviour.

Just an idea with the very little I know from what you pasted,

-- 
Zach Dennis
http://www.continuousthinking.com (personal)
http://www.mutuallyhuman.com (hire me)
http://ideafoundry.info/behavior-driven-development (first rate BDD training)
@zachdennis (twitter)


More information about the rspec-users mailing list