Joseph DelCioppio
2010-Jun-11 02:07 UTC
[rspec-users] Stubbing before_filters with RSpec and stub!
Guys, I''ve got a private controller method which acts as a before_filter that I''m trying to stub. class TasksController < ApplicationController before_filter :load_user ...... private def load_user if current_user.id == params[:user_id].to_i @user = current_user else flash[:notice] = "Sorry but you can''t view other people''s tasks." redirect_to root_path end end end describe TasksController do before(:each) do @user = Factory(:user) sign_in @user @task = Factory(:task) User.stub_chain(:where, :first).and_return(@user) controller.stub!(:load_user).and_return(@user) end ....... end However, even though I''m stubbing load_user, the actual function is still being called, because I can make all my tests either pass/fail if I simply have load_user neglect to return @user. If I have stubbed load_user, should it just always return @user, no matter what I do to the actual controller method? I thought that this was the point of stubbing, that way if I change load_user in the future, only the tests specifically designed to exercise load_user will fail, but the rest of my suite will still pass. I''m going to post my entire controller and spec and provide the Gist links in case the abbreviated versions I gave aren''t enough. http://gist.github.com/433942 Thanks in advance, Joe
What I would do maybe not the best solution is to control what is returned in current user so if you want to test that the redirect works then make current_user return nil then the redirect should work and to get the filter to pass stub the current user to return an instance that has an id that matches the param passed in On 11/06/2010 03:07, Joseph DelCioppio wrote: Guys, I''ve got a private controller method which acts as a before_filter that I''m trying to stub. class TasksController < ApplicationController before_filter :load_user ...... private def load_user if current_user.id == params[:user_id].to_i @user = current_user else flash[:notice] = "Sorry but you can''t view other people''s tasks." redirect_to root_path end end end describe TasksController do before(:each) do @user = Factory(:user) sign_in @user @task = Factory(:task) User.stub_chain(:where, :first).and_return(@user) controller.stub!(:load_user).and_return(@user) end ....... end However, even though I''m stubbing load_user, the actual function is still being called, because I can make all my tests either pass/fail if I simply have load_user neglect to return @user. If I have stubbed load_user, should it just always return @user, no matter what I do to the actual controller method? I thought that this was the point of stubbing, that way if I change load_user in the future, only the tests specifically designed to exercise load_user will fail, but the rest of my suite will still pass. I''m going to post my entire controller and spec and provide the Gist links in case the abbreviated versions I gave aren''t enough. http://gist.github.com/433942 Thanks in advance, Joe _______________________________________________ rspec-users mailing list rspec-users-GrnCvJ7WPxnNLxjTenLetw@public.gmane.org http://rubyforge.org/mailman/listinfo/rspec-users
David Chelimsky
2010-Jun-12 14:49 UTC
[rspec-users] Stubbing before_filters with RSpec and stub!
On Jun 12, 2010, at 9:05 AM, Stephen Smithstone wrote:> On 11/06/2010 03:07, Joseph DelCioppio wrote: >> >> Guys, >> >> I''ve got a private controller method which acts as a before_filter >> that I''m trying to stub. >> >> class TasksController < ApplicationController >> before_filter :load_user >> >> ...... >> >> private >> >> def load_user >> if current_user.id == params[:user_id].to_i >> @user = current_user >> else >> flash[:notice] = "Sorry but you can''t view other people''s >> tasks." >> redirect_to root_path >> end >> end >> end >> >> >> describe TasksController do >> >> before(:each) do >> @user = Factory(:user) >> sign_in @user >> @task = Factory(:task) >> User.stub_chain(:where, :first).and_return(@user) >> controller.stub!(:load_user).and_return(@user) >> end >> >> ....... >> end >> >> However, even though I''m stubbing load_user, the actual function is >> still being called, because I can make all my tests either pass/fail >> if I simply have load_user neglect to return @user. >> >> If I have stubbed load_user, should it just always return @user, no >> matter what I do to the actual controller method? I thought that this >> was the point of stubbing, that way if I change load_user in the >> future, only the tests specifically designed to exercise load_user >> will fail, but the rest of my suite will still pass. >> >> I''m going to post my entire controller and spec and provide the Gist >> links in case the abbreviated versions I gave aren''t enough. >> >> http://gist.github.com/433942 > What I would do maybe not the best solution is to control what is returned in current user so if you want to test that the redirect works then > make current_user return nil then the redirect should work and to get the filter to pass stub the current user to return an instance that has an id that matches the param passed inThat''s actually a very common solution to this problem. The caller of the filter doesn''t actually store the user, it expects the filter to set the @user instance variable. Cheers, David -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20100612/babb8061/attachment-0001.html>