I was trying to test a simple index view, which has following code inside:
- if can? :destroy, MyModel
%th Options
MyModelsController
has following options (Inherited Resources + CanCan + Devise):
class MyModelsController < ApplicationController
inherit_resources
nested_belongs_to :mymodel
before_filter :authenticate_user!
load_and_authorize_resource :project
load_and_authorize_resource :mymodel, :through => :project
When running specs, it crashes at the line - if can? :destroy, MyModel
Failure/Error: render
ActionView::Template::Error:
undefined method `authenticate' for nil:NilClass
There's no traceback, nothing to base on...
I thought that maybe I'm not authorized and signed when testing views, but Devise::TestHelpers
should only be included in controller tests (and that's how I have it).
I was trying to override method can? in both Ability
and the controller, but that gave no effect.
This is described in the CanCan docs for controller testing, and can also be modified to apply to view specs. Here's one way to do it:
require 'spec_helper'
describe "mymodel/index.html.erb" do
before(:each) do
assign(:my_model,mock_model(MyModel))
@ability = Object.new
@ability.extend(CanCan::Ability)
controller.stub(:current_ability) { @ability }
end
context "authorized user" do
it "can see the table header" do
@ability.can :destroy, MyModel
render
rendered.should have_selector('th:contains("Options")')
end
end
context "unauthorized user" do
it "cannot see the table header" do
render
rendered.should_not have_selector('th:contains("Options")')
end
end
end