RSpec on Controller and Stubbing
I am pretty new to using rspec and am trying to write my tests for my controllers. I have this controller (I am using mocha for stubbing):
class CardsController < ApplicationController
before_filter :require_user
def show
@cardset = current_user.cardsets.find_by_id(params[:cardset_id])
if @cardset.nil?
flash[:notice] = "That card doesn't exist. Try again."
redirect_to(cardsets_path)
else
@card = @cardset.cards.find_by_id(params[:id])
end
end
end
I am trying to test this action with something like this:
describe CardsController, "for a logged in user" do
before(:each) do
@cardset = Factory(:cardset)
profile = @cardset.profile
controller.stub!(:current_user).and_return(profile)
end
context "and created card" do
before(:each) do
@card = Factory(:card)
end
context "with get to show" do
before(:each) do
get :show, :cardset_id => @cardset.id, :id => @card.id
end
context "with valid cardset" do
before(:each) do
Cardset.any_instance.stubs(:find).returns(@cardset)
end
it "should assign card" do
assigns[:card].should_not be_nil
end
it "should assign cardset" do
assigns[:cardset].should_not be_nil
end
end
end
end
end
The "should assign cardset" test passes, but I cannot figure out how to properly stub this line @card = @cardset.cards.find_by_i开发者_如何转开发d(params[:id])
for the "should assign card" test. What is the best way of testing this action, or if I'm on the right track how would I properly stub my Model calls?
Ok, deleted a previous answer which was wrong.
First: you are stubbing find
not find_by_id
. Although you don't need to use find_by_id since that is the default for find. So use find
Second: the before :each
ordering is going to call the get :show
before the you stub Cardset
Third: check your test.log and make sure you are not getting redirected. Your require_user
action might cause a redirect before current_user
is even set.
class CardsController < ApplicationController
...
@card = @cardset.cards.find(params[:id])
...
end
describe CardsController, "for a logged in user" do
before(:each) do
@cardset = Factory(:cardset)
profile = @cardset.profile
controller.stub!(:current_user).and_return(profile)
end
context "and created card" do
before(:each) do
@card = Factory(:card)
end
context "with get to show" do
context "with valid cardset" do
before(:each) do
Cardset.any_instance.stubs(:find).returns(@cardset)
get :show, :cardset_id => @cardset.id, :id => @card.id
end
it "should assign card" do
assigns[:card].should_not be_nil
end
it "should assign cardset" do
assigns[:cardset].should_not be_nil
end
end
end
end
end
The stubs that I ended up looking for where these
Cardset.stubs(:find_by_id).returns(@cardset)
@cardset.cards.stubs(:find_by_id).returns(@card)
精彩评论