Hey guys, i have this before-filter in my application-controller: def login_required if !current_user redirect_to join_welcome_path and return end end This before-filter is prepended before all other before-filters in my application_controller.rb like this prepend_before_filter :login_required, Now i want to test a controller which should only be accessible if the user is logged in like that: describe "new action" do describe "before-filter requirements are not met" do before(:each) do activate_authlogic end it "should redirect to join_welcome_path if not logged in" do controller.stub(:login_required).and_return(false) get :new response.should redirect_to(join_welcome_path) end The thing is, I would have expected this spec to pass - a call to "new" invokes the login-required before-filter which redirects to the join_welcome_path. Instead i get: NoMethodError in ''Shopping::PaymentsController new action before- filter requirements are not met should redirect to join_welcome_path if not logged in'' undefined method `current_cart_size'' for nil:NilClass which is from a before-filter which is triggered _after_ the login- required before-filter. How do I even get there? As far as I understood the docs, this line: controller.stub(:login_required).and_return(false) should cause a redirect, so how do i even get to subsequent before- filters? In a nutshell: Why do I even reach subsequent before-filters? What am I doing wrong here?
On Sun, Jan 3, 2010 at 6:56 PM, jollyroger <timo.roessner at googlemail.com>wrote:> Hey guys, > > i have this before-filter in my application-controller: > > def login_required > if !current_user > redirect_to join_welcome_path and return > end > end > > This before-filter is prepended before all other before-filters in my > application_controller.rb like this > > prepend_before_filter :login_required, > > Now i want to test a controller which should only be accessible if > the user is logged in like that: > > describe "new action" do > > describe "before-filter requirements are not met" do > > before(:each) do > activate_authlogic > end > > it "should redirect to join_welcome_path if not logged in" do > controller.stub(:login_required).and_return(false) > get :new > response.should redirect_to(join_welcome_path) > end > > The thing is, I would have expected this spec to pass - a call to > "new" invokes the login-required before-filter which redirects to the > join_welcome_path. > > Instead i get: > > NoMethodError in ''Shopping::PaymentsController new action before- > filter requirements are not met should redirect to join_welcome_path > if not logged in'' > undefined method `current_cart_size'' for nil:NilClass > > which is from a before-filter which is triggered _after_ the login- > required before-filter. > > How do I even get there? > As far as I understood the docs, this line: > > controller.stub(:login_required).and_return(false) > > should cause a redirect,That is not correct. That line completely replaces the login_required() method with a stub that returns false. The code in the real login_required() method is not executed at all, and therefore the redirect does not happen.> so how do i even get to subsequent before- > filters?Filters only halt execution if they invoke a redirect or return. In this case, because the filter is stubbed and the redirect is never called, execution continues. In a nutshell:> > Why do I even reach subsequent before-filters? > What am I doing wrong here? >You have a couple of options here, but I think the simplest thing would be to stub current_user instead of login_required: it "should redirect to join_welcome_path if not logged in" do controller.stub(:current_user).and_return(nil) get :new response.should redirect_to(join_welcome_path) end HTH, David -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20100104/a1877ee5/attachment.html>
Hi David, well, the way you put it it all sounds totally logical...:-) Thanks a lot for the suggestions, I guess I need to improve my specs.... On Jan 4, 11:20?am, David Chelimsky <dchelim... at gmail.com> wrote:> On Sun, Jan 3, 2010 at 6:56 PM, jollyroger <timo.roess... at googlemail.com>wrote: > > > > > Hey guys, > > > i have this before-filter in my application-controller: > > > ?def login_required > > ? ?if !current_user > > ? ? ?redirect_to join_welcome_path and return > > ? ?end > > ?end > > > This before-filter is prepended before all other before-filters in my > > application_controller.rb like this > > > ?prepend_before_filter :login_required, > > > Now i want ?to test ?a controller which should only be accessible if > > the user is logged in like that: > > > ?describe "new action" do > > > ? ?describe "before-filter requirements are not met" do > > > ? ? ?before(:each) do > > ? ? ? ?activate_authlogic > > ? ? ?end > > > ? ? ?it "should redirect to join_welcome_path if not logged in" do > > ? ? ? ?controller.stub(:login_required).and_return(false) > > ? ? ? ?get :new > > ? ? ? ?response.should redirect_to(join_welcome_path) > > ? ? ? end > > > The thing is, I would have expected this spec to pass - a call to > > "new" invokes the login-required before-filter which redirects to the > > join_welcome_path. > > > Instead i get: > > > NoMethodError in ''Shopping::PaymentsController new action before- > > filter requirements are not met should redirect to join_welcome_path > > if not logged in'' > > undefined method `current_cart_size'' for nil:NilClass > > > which is from a before-filter which is triggered _after_ the login- > > required before-filter. > > > How do I even get there? > > As far as I understood the docs, this line: > > > ?controller.stub(:login_required).and_return(false) > > > should cause a redirect, > > That is not correct. That line completely replaces the login_required() > method with a stub that returns false. The code in the real login_required() > method is not executed at all, and therefore the redirect does not happen. > > > so how do i even get to subsequent before- > > filters? > > Filters only halt execution if they invoke a redirect or return. In this > case, because the filter is stubbed and the redirect is never called, > execution continues. > > In a nutshell: > > > > > Why do I even reach subsequent before-filters? > > What am I doing wrong here? > > You have a couple of options here, but I think the simplest thing would be > to stub current_user instead of login_required: > > it "should redirect to join_welcome_path if not logged in" do > ? controller.stub(:current_user).and_return(nil) > ? get :new > ? response.should redirect_to(join_welcome_path) > end > > HTH, > David > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users