ruby on rails - Probar vistas que usan CanCan y Devise con RSpec
ruby-on-rails (5)
Estaba intentando probar una vista de índice simple, que tiene el siguiente código:
- if can? :destroy, MyModel
%th Options
MyModelsController
tiene las siguientes opciones (Recursos heredados + CanCan + Diseño):
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
Cuando se ejecutan las especificaciones, se bloquea en la línea - if can? :destroy, MyModel
- if can? :destroy, MyModel
Failure/Error: render
ActionView::Template::Error:
undefined method `authenticate'' for nil:NilClass
No hay rastro, nada en que basarse ...
Pensé que tal vez no estoy autorizado y firmado al probar vistas, pero Devise::TestHelpers
solo debería incluirse en las pruebas de controlador (y así es como lo tengo).
Estaba tratando de anular el método puede? tanto en Ability
como en el controlador, pero eso no dio efecto.
El código ''antes: cada'' publicado por zetetic no funciona para mí. Mis puntos de vista sobre el ''can?'' método porque ''current_ability'' en la vista devuelve nil. Lo arreglé utilizando este código ''antes: cada'' en su lugar:
@ability = Ability.new(user)
assign(:current_ability, @ability)
controller.stub(:current_user, user)
view.stub(:current_user, user)
El código anterior simula un inicio de sesión.
El problema con la solución de la wiki de CanCan es que requiere una @ability. can ...
@ability. can ...
en cada ejemplo, lo que no se siente muy SECO.
Además, en realidad no apaga las habilidades en sí mismas, sino el método que devuelve la capacidad del controlador. La habilidad no es un código auxiliar y, por lo tanto, se verifican las habilidades.
Si estás usando Rspec y quieres probar solo el controlador (y no sus habilidades), aquí tienes cómo apagarlo:
before(:each) do
ability = mock(:ability).as_null_object
controller.stub(:current_ability).and_return(ability)
end
Esto funciona porque as_null_object
devuelve valores veraces para todos los métodos, por lo que los métodos de verificación de capacidad pasan.
En su spec_helper:
config.include Devise::TestHelpers, :type => :view
En su vista espec.
controller.stub!(current_user: [some user])
view.stub!(current_user: [some user])
Esto se describe en los documentos de CanCan para la prueba del controlador , y también se puede modificar para aplicar para ver las especificaciones. Aquí hay una forma de hacerlo:
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
Para la nueva sintaxis de RSpec 3.0
before(:each) do
assign(:my_model,mock_model(MyModel))
@ability = Object.new.extend(CanCan::Ability)
allow(controller).to receive(:current_ability).and_return(@ability)
end