2016-10-05 6 views
1

Railscast suivant #385 & #386 J'ai ajouté une autorisation à mon application Rails 4 (rails 4.2.6, rspec-rails 3.4.2). Après l'ajout de l'autorisation, toutes les spécifications de mon contrôleur échouent.Les spécifications du contrôleur RSpec échouent après l'ajout de l'autorisation à l'application Rails4

Mes caractéristiques techniques sont toujours valides car dans la spécification, je me connecte en tant qu'admin pour effectuer des actions qui ne sont pas autorisées aux visiteurs (: edit,: update ...). Si je fais toutes les actions autorisées à un visiteur mes spécifications de contrôleur passent. Cependant, toute action que seul l'administrateur peut effectuer échouera dans la spécification du contrôleur.

Le générateur d'échafaudage crée un vide

let(:valid_session) { { } } 

qu'il dit dans les commentaires:

# This should return the minimal set of values that should be in the session in order to pass any filters (e.g. authentication) defined in MyController.

Cependant, je ne sais pas comment configurer ceci: valid_session pour permettre l'authentification de passer.

Lorsque je tente la solution a écrit dans ce question:

def valid_session 
    controller.stub!(:signed_in?).and_return(true) 
end 

Je reçois cette erreur:

NoMethodError: 
     undefined method `stub' for #<MyController 

Depuis, tous les nombreux chemins de dérivation de la logique doit être testé à un niveau inférieur (c'est-à-dire la spécification du contrôleur) plutôt que la spécification de fonctionnalité, comment puis-je faire passer les spécifications du contrôleur?

Comment configurer valid_session ou quelle autre méthode puis-je utiliser pour passer l'autorisation dans les spécifications de mon contrôleur?

+0

Impossible de publier un exemple de code ici, donc de répondre à la réponse. –

Répondre

2

Ok, avec l'aide de ce blog j'ai pu obtenir mes tests de contrôleur pour passer après l'ajout d'autorisation aux contrôleurs.

Dans spec/support/aides/controller_macros.rb Je définis ces méthodes:

module ControllerMacros 
    def login_admin 
    user = FactoryGirl.create(:admin) 
    allow(controller).to receive(:current_user).and_return(user) 
    end 
    def login_member 
    user = FactoryGirl.create(:member) 
    allow(controller).to receive(:current_user).and_return(user) 
    end 
    def login_visitor 
    allow(controller).to receive(:current_user).and_return(nil) 
    end 
end 

Pour activer ces méthodes dans spec/support/helpers.rb:

RSpec.configure do |config| 
    config.include ControllerMacros, type: :controller 
end 

Et puis l'implémenter dans la spécification du contrôleur, spec/controllers/topics_controller_spec.rb:

require 'rails_helper' 
RSpec.describe TopicsController, type: :controller do 
    let(:valid_attributes) { 
    { :name => "MyTopic" } 
    } 
    let(:invalid_attributes) { 
    { :name => nil } 
    } 
    before(:each) do 
    login_admin 
    end 
    describe "GET #index" do 
    it "assigns all topics as @topics" do 
     login_visitor 
     topic = Topic.create! valid_attributes 
     get :index, {} 
     expect(assigns(:topics)).to eq([topic]) 
    end 
    end 
    describe "GET #show" do 
    it "assigns the requested topic as @topic" do 
     login_visitor 
     topic = Topic.create! valid_attributes 
     get :show, {:id => topic.to_param} 
     expect(assigns(:topic)).to eq(topic) 
    end 
    end 
    describe "GET #new" do 
    it "assigns a new topic as @topic" do 
     get :new, {} 
     expect(assigns(:topic)).to be_a_new(Topic) 
    end 
    end 
[...] 
end 

Ceci se connectera en tant qu'administrateur avant chaque test. Notez que vous devez tester chaque action au niveau le plus bas autorisé, de sorte que show et index soient testés en tant que visiteur (non connecté). Si toutes les actions nécessitent une autorisation d'administrateur, vous pouvez utiliser before do au lieu de before(:each) do pour économiser un peu de temps lors des tests.

Enfin, vous devez supprimer toute mention de valid_session de la spécification.

0

Vous pouvez simplement créer un utilisateur.

module ControllerMacros 
    def login_user(user = nil, options = {}) 
    before(:each) do 
    @request.env["devise.mapping"] = Devise.mappings[:user] 
    @user = user || FactoryGirl.create(options[:user] || :user) 
    sign_in @user 
    end 
end 
+0

Merci Jason, mais je n'utilise pas Devise, donc je n'ai pas la fonction sign_in à ma disposition. Aussi, où pourrais-je utiliser le code que vous avez fourni? Comment l'appeler de la spécification du contrôleur? – MERM

+0

Le code serait ajouté à un dossier de support dans une classe de votre dossier de spécifications. Vous pouvez le créer, puis assurez-vous qu'il est en cours de chargement. Si vous n'utilisez pas le concepteur, vous devriez être en mesure de macro tout moyen que vous utilisez pour vous connecter à l'utilisateur de toute façon. –

+0

"devrait pouvoir macro" pas vraiment sûr de ce que cela signifie. Pourriez-vous pointer vers un exemple> – MERM