Home How to test that a before_filter works correctly with RSpec in Rails
Reply: 2

How to test that a before_filter works correctly with RSpec in Rails

Kostas
1#
Kostas Published in 2011-05-04 09:41:33Z

I have a check_user_access_control before_filter in my ApplicationController that checks the logged user's roles and permissions before it lets him through. I am trying to write some tests on it and I can't find a good way of doing it.

For simple index actions I simply do:

it "allows access to mod" do
  login_as(Factory(:mod)) # this is a spec helper
  get :index
  response.code.should == "200"
end

and it works just fine. For edit/show/create and other actions that need some params, interactions with the database and possible redirect after they run, it needs too many other stuff to be stubbed.

Is there a way to test if a specific action has been called after the before_filters? I am looking for something like controller.should_receive(:action_name) (which doesn't work) to replace the response.code.should == "200" line with.

versions: rails 3.0.4 and rspec 2.5

I tried another approach. We have a method in ApplicationController called redirect_to_login that I am now checking for with controller.should_receive(:redirect_to_login) and works.

While it detects correctly if the user is allowed or not, it stubs the method, which means that the controller action is run whether or not the user is allowed. Moreover the action depends on params and database and we don't want that.

If now I stub the action method with controller.stub!(:action_name), the action is not run but RSpec is still looking for the template. Well, some actions don't have templates, they just end with a redirect_to :action => :somewhere_else or render :text => "foobar" which at this point we don't care about.

In sort, what I need now is to find a way to make RSpec NOT worry about the template's existence.

nathanvda
2#
nathanvda Reply to 2011-05-04 13:40:30Z

When stubbing, you could still give a dummy implementation. Inside that implementation you could then raise an error, to make sure all execution is halted, or you do a redirect anyway.

E.g.

controller.should_receive(:redirect_to_log) { redirect_to login_url }

or

controller.should_receive(:redirect_to_log) { raise StandardError.new('login error') }
expect { get :index }.to raise_error

For more information check out the awesome rspec documentation.

Hope it helps.

Community
3#
Community Reply to 2017-05-23 10:32:38Z

To extend @nathanvda's answer:

When stubbing, you could still give a dummy implementation. Inside that implementation [...] do a redirect anyway.

You need to specify controller in the block:

expect(controller).to receive(:redirect_to_log) { controller.redirect_to login_url }

RSpec has a matcher that is also called redirect_to that takes precedence when looking up the method. Calling it directly on the controller works around that.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.506278 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO