2017-10-20 1 views
1

ich für den dritten Tag leide, kann ich nicht verstehen, warum ich nicht den nächsten Test bestehen:CanCan :: AccessDenied mit factory_girl und cancan, Wie korrekt die Fabrik zu schreiben?

4) Error: 
ArticlesControllerTest#test_should_get_index_if_admin: 
CanCan::AccessDenied: You are not authorized to access this page. 
    test/controllers/articles_controller_test.rb:22:in `block in <class:ArticlesControllerTest>' 

Was mache ich falsch? Hilf mir bitte!

Ich habe alte Anwendung (Schienen 4.2), mit vielen Fixtures Daten.

Ich versuche meine Testumgebung von Fixtures auf factory_girl zu migrieren. Ich bin neu in diesem Bereich.

Jetzt mit Ich bin:

  • cancancan + ersinnen
  • factory_girl + Testcase

Meine Artikel Controller:

class ArticlesController < ApplicationController 
    load_and_authorize_resource 
    before_filter :authenticate_user!, except: [:show] 

    def index 
    @articles = Article.paginate(page: params[:page], per_page: 10).includes(:translations) 
    end 
end 

Ability.rb:

Class Ability 
include CanCan::Ability 

def initialize(user) 
    user ||= User.new 

    # Everybody 
    can :show, [Article] 

    if user.admin? 
    can :manage, Article 
    end 
end 
end 

Meine Fabrik article.rb ist sehr einfach:

FactoryGirl.define do 
factory :article do 
    content "MyText" 

    factory :one_article 
    factory :two_article 
end 
end 

Meine Fabrik user.rb ist einfach zu:

FactoryGirl.define do 
    factory :user do 
    sequence(:email) { |n| "user#{n}@mail.ru" } 
    password "password" 
    password_confirmation "password" 
    after(:create) {|u| u.roles_mask = 4} 
    profile 

    factory :valid_admin do 
     first_name "Administrator" 
     last_name "Administrator" 
     association :profile, factory: :admin_profile 
     after(:create) {|u| u.roles_mask = 2} 
    end 
    end 
end 

Meine Artikel Controller-Test:

require 'test_helper' 

class ArticlesControllerTest < ActionController::TestCase 
    include Devise::Test::ControllerHelpers 

    setup do 
    @article = create(:one_article) 
    @admin = create(:valid_admin) 
    end 

    test 'should get index if admin' do 
    sign_in @admin 

    ability = Ability.new(@admin) 
    assert ability.can? :index, Article 

    get :index 
    assert_response :success 
    assert_not_nil assigns(:articles) 
    end 
end 

Info durch Hebel:

[1] pry(#<ArticlesControllerTest>)> sign_in @admin 
=> [[20709], "9BET5RWNuJPrGHUFi86d"] 
[2] pry(#<ArticlesControllerTest>)> ability = Ability.new(@admin) 
=> #<Ability:0x0000000c3c5ff8 
@rules= 
    [#<CanCan::Rule:0x0000000c3c5f80 
    @actions=[:show], 
    @base_behavior=true, 
    @block=nil, 
.............<<Many lines>> .............. 
[3] pry(#<ArticlesControllerTest>)> assert ability.can? :index, Article 
=> true 
[4] pry(#<ArticlesControllerTest>)> get :index 
CanCan::AccessDenied: You are not authorized to access this page. 
from /home/da/.rvm/gems/[email protected]/gems/cancancan-1.16.0/lib/cancan/ability.rb:217:in `authorize!' 

Vielen Dank im Voraus für Ihre Hilfe!

+0

Wenn dies eine neue App ist. Außerdem würde ich einen separaten Test verwenden, um deine Fähigkeitsklasse isoliert zu testen, anstatt es hier zu tun. – max

+1

Ich verstehe auch nicht, was Sie mit der Fabrik machen wollen. Ich benutze FactoryGirl mit ffaker normalerweise, um zufällige Daten zu erzeugen. Fabriken wie 'factory: one_article' zu ​​definieren, riecht nach einer Leuchte. Fabriken sind keine Fixtures.Sie sind Fabriken, die einzigartige Gegenstände schaffen sollten. Wenn Sie die Werte Ihrer Fabriken in Ihre Spezifikationen fest codieren, tun Sie es falsch. Schlecht: 'expect (Seite) .to have_link (" Foo ")' Gut: 'expect (Seite) .to have_link (article.name)' – max

+0

Ich habe das Prinzip des Testens mit Hilfe einer Tasse jetzt wirklich nicht verstanden Ich bin in dieser Sache fortgeschrittener geworden) danke für deinen Tipp! Ich habe den zusätzlichen Müll entfernt, einige Entitäten im Merkmal neu gemacht, und diese Fehler sind verschwunden! – nilid

Antwort

1

Dies sind die Richtlinien für die Entwicklung, Sie müssen eine Methode erstellen, um den Benutzer als Administrator anmelden. Dies ist die login_method Sie

Controller-Tests (Test :: Unit) erstellen müssen

Um als Administrator für einen bestimmten Testfall unterschreiben, nur tun:

class SomeControllerTest < ActionController::TestCase 
    # For Devise >= 4.1.1 
    include Devise::Test::ControllerHelpers 
    # Use the following instead if you are on Devise <= 4.1.0 
    # include Devise::TestHelpers 

    def setup 
    @request.env["devise.mapping"] = Devise.mappings[:admin] 
    sign_in FactoryGirl.create(:admin) 
    end 
end 

Hinweis: Wenn Sie das Bestätigungsmodul verwenden, sollten Sie innerhalb der Factory ein Confirmed_at-Datum festlegen oder einen Anruf bestätigen. vor sign_in.

ist hier die Grundlagen in Ihrem Werk vorzubereiten: Verwendung `ActionDispatch :: IntegrationTest` statt einen Controller Test

FactoryGirl.define do 
    factory :account do 
    email { Faker::Internet.email } 
    password "password" 
    password_confirmation "password" 
    confirmed_at Date.today 
    end 
end 
+0

Dies ist eine großartige Antwort! – Sean

+0

@Sean Vielen Dank –

+0

Vielen Dank für Ihre Antwort, aber ich verwende rspec – nilid

Verwandte Themen