[rspec-users] Controller spec: testing that scope is set

Michael Schuerig michael at schuerig.de
Sun Apr 19 21:47:22 EDT 2009


On Monday 20 April 2009, David Chelimsky wrote:

> >> Consider this alternative:
> >>
> >> describe PeopleController do
> >>   describe "GET index" do
> >>     it "assigns a list of all people filtered by virtual name
> >> attributes" do people = [mock_model(Person)]
> >>       Person.stub!(:all).and_return(people)
> >>      
> >> people.should_receive(:with_virtual_names).and_return(people) get
> >> :index
> >>     end
> >>   end
> >> end
> >>
> >> class PeopleController
> >>   def index
> >>     @people = PeopleController.all.with_virtual_names
> >>   end
> >> end
> >
> > That code is sclerotic. I'm building a RIA-client that only
> > requests JSON-formatted data from the server. Say, I add a date of
> > birth column to the people grid. Then the most I want to (and have
> > to) do is ensure that the requisite attribute is whitelisted for
> > querying and contained in the response data. (Yes, I have JSON
> > "views" with accompanying specs.)
> >
> > Taking your non-generic approach, I'd have to repeatedly write and
> > explicitly test, very similar code. Consider adding date of birth
> > for sorting and filtering to your example. Then consider writing
> > another controller that does roughly the same for movies with
> > titles and release dates. You'll end up with repetitive code. Of
> > course, you're going to factor out the repetition -- and that's
> > where I already am.
> >
> > So, long story short, I still think I could make good use of a way
> > to define an expectation for a specific scope in effect during a
> > #find. Apart from my current case, this would make it possible to
> > check on dynamic scopes introduced in Rails 2.3.
>
> So what does the controller's index method actually look like?

class PeopleController < ApplicationController
  ...
  def index
    respond_to do |format|
      format.html { render :layout => false }
      format.json do
        @people = Person.all(
          :offset => @offset_limit[0],
          :limit  => @offset_limit[1])
        @count = Person.count
        render
      end
    end
  end
  ...

# app/views/people/index.json.rb
{
  :identifier => Person.primary_key,
  :totalCount => @count,
  :items => @people.map { |p|
    render :partial => 'people/item', :locals => { :person => p }
  }
}

# app/views/people/_item.json.rb
{
  :id => person.id,
  :name => person.name,
  :dob => person.date_of_birth
}

:offset and :limit are the only warts, but I can't set them in a scope 
as that would affect the total #count to, not just #find.

Michael

-- 
Michael Schuerig
mailto:michael at schuerig.de
http://www.schuerig.de/michael/



More information about the rspec-users mailing list