How to test named_scope

how a can test this controller using rspec

#home controller
def home
@recents = Article.publisheds.with_authorship.paginate(:page =>
1, :per_page => 10, :total_entries => 10)
@highlight = Article.publisheds.highlight.with_authorship
end

#article model

named_scope :publisheds, lambda { { :conditions => [“published_at
<= ? and status = ‘publicado’”, Time.now.utc] } }
named_scope :highlight, lambda { { :conditions => [“highlight IS NOT
NULL and highlight <> ‘’”], :order => “highlight desc, published_at
desc”, :limit => 4 } }
named_scope :with_authorship, :include => [:authorships, :authors]

i do this bat dont work:

describe GeneralController do
def mock_article(stubs={})
@mock_article ||= mock_model(Article, stubs)
end

describe “GET index” do
it “should expose article as @articles” do
articles = [mock_article]
Article.should_receive(:publisheds).and_return(articles)
articles.should_receive(:with_authorship).and_return(articles)
articles.should_receive(:paginate).with(:per_page =>
10,:total_entries=>10, :page => 1).and_return(articles)
get :home
assigns[:recents].should == articles
end
end
end

On Wed, Oct 6, 2010 at 12:44 PM, Cyrus [email protected]
wrote:

how a can test this controller using rspec

#home controller
def home
@recents = Article.publisheds.with_authorship.paginate(:page => 1, :per_page
=> 10, :total_entries => 10)
@highlight = Article.publisheds.highlight.with_authorship
end

You can do this with stub_chain, but I would not recommend it:

describe “GET home” do
it “assigns recent articles to @recents” do
recent = mock_model(Article)
Article.stub_chain(“publisheds.with_authorship.paginate”) { [recent]
}
assigns(:recents).should eq(recents)
end

it “assigns the highlight to @highlight” do
highlight = mock_model(Highlight)
Article.stub_chain(“publisheds.highlight.with_authorship”) {
highlight }
assigns(:highlight).should eq(highlight)
end
end

Instead, I’d recommend using the spec (written first) to drive out
simpler APIs on Article.

describe “GET home” do
before do
Article.stub(:recents)
Article.stub(:highlight)
end

it “assigns recent articles to @recents” do
recents = [mock_model(Article)]
Article.stub(:recents) { recents }
get :home
assigns(:recents).should eq(recents)
end

it “paginates the recent articles” do
recents = [mock_model(Article)]
recents.should_receive(:paginate).with(:page => 1, :per_page =>
10, :total_entries => 10)
get :home
end

it “assigns the highlight to @highlight” do
highlight = mock_model(Highlight)
Article.stub(:highlight) { highlight }
assigns(:highlight).should eq(highlight)
end
end

Now the controller code gets a bit simpler:

def home
@recents = Article.recents.paginate(:page => 1, :per_page => 10,
:total_entries => 10)
@highlight = Article.highlight
end

And the examples specify the assorted responsibilities.

Now you can spec the recents and highlight methods on the Article
model, but instead of mentioning the named scopes and trying to stub
everything that happens internally on Article, just set up the example
data that you need:

describe “recents” do
it “includes articles written within the past two weeks” do
too_old = Factory(:article, :published_at => 15.days.ago)
just_young_enough = Factory(:article, :published_at => 14.days.ago)
more_than_young_enough = Factory(:article, :published_at =>
13.days.ago)
Article.recents.should =~ [just_young_enough,
more_than_young_enough]
end
end

etc, etc.

This way the responsibilities are nicely separated, the surface area
between the controller and the model is smaller and more targeted, and
you are free to refactor Article below a simpler API.

HTH,
David