ruby-on-rails ruby rspec devise cancan

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