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