2016-08-13 20 views
1

私は、Pundit-matchers gemと一緒に私の現在のプロジェクトでPunditを使用し始めました。Rails Pundit Policy SpecテストがNoMethodErrorで失敗しました

これまでのところ、一般的には私のために働いているようですが、私のテストでは問題があります。

私は一般的にpundit-matchers readmeとThunderbolt labsのブログ(http://thunderboltlabs.com/blog/2013/03/27/testing-pundit-policies-with-rspec/)の例に従おうとしました。

これは私のポリシーファイルです。

#app/policies/procedure_policy.rb 
class ProcedurePolicy 
    attr_reader :user, :procedure 

    def initialize(user, procedure) 
     @user = user 
     @procedure = procedure 
    end 

    def index? 
     user.admin? 
    end 

end 

そして、これは私の3つのテストの

require 'rails_helper' 

describe ProcedurePolicy do 
    subject {described_class.new(user, procedure)} 

    let(:procedure) {FactoryGirl.create(:procedure)} 

    context "for a guest" do 
     let(:user) {nil} 
     it {is_expected.not_to permit_action(:index)} 
    end 

    context "for a non-admin user" do 
     let(:user) {FactoryGirl.create(:user)} 
     it {is_expected.not_to permit_action(:index)} 
    end 

    context "for an admin user" do 
     let(:user) {FactoryGirl.create(:admin_user)} 
     it {is_expected.to permit_action(:index)} 
    end 

end 

2渡す私policy_specファイルです。 "for a non-admin user"および"for an admin user"のもの。 "for a guest"テストは、今私は理由を理解

NoMethodError: 
     undefined method `admin?' for nil:NilClass 

で失敗します。 nil#admin?メソッドを持たない私のProcedurePolicyクラスの#index?メソッドに渡しています。しかし、私がオンラインで見つけたすべてのサンプル仕様は、まさにこれを行っています。私は何を見ていないのですか?

私は本当に明白な何かを紛失している場合はお詫び申し上げます。私は数年間コーディングをしていませんでした。

+0

[航行安全演算子]のために行きます。 (https:// stackoverflow。com/questions/36812647/what-does-amp-sum-in-ruby)defインデックス?ユーザー&.admin?終了 –

答えて

1

文脈「の訪問者であることは、」テストの承認のためであります現在システムで認証されているユーザーがいない場合に試行されます。ユーザはログインしていないため、ユーザレコード/オブジェクトは存在しません。ユーザオブジェクトのが存在しません。nilです。このため、Thunderbolt Labsとpundit-matchersの両方の例では、訪問者を表すためにnilが使用されています。 nilオブジェクトにはadmin?メソッドがないため、エラーが発生します。

ポリシー内のnil/guestユーザーを正しく処理するには、ユーザーオブジェクトが直接管理されているか、Railsでpresent?メソッドを使用してユーザーが管理者かどうかを確認する前にユーザーオブジェクトが存在するかどうかを確認します。

def index? 
    user.present? && user.admin? 
end 

か、単に:

def index? 
    user && user.admin? 
end 

何のユーザーが署名されていないときには、このような工夫としてその認証システムがcurrent_userメソッドからnilを返す見つける

2

Punditは、メソッドをuserに設定します。通常、Deviseやカスタムソリューションなどの認証システムによって提供されます。これは、大部分のシナリオでは、Punditロジックをヒットする前に常に認証のレイヤーがあることが期待されるため、そこに到達するとuserがnilに設定されることはありません。

あなたは評論家の権限は認証なしで直接操作したい場合は、あなたのポリシー定義でそれを処理する必要が、例:

class ProcedurePolicy  
    def index? 
    user.present? && user.admin? 
    end 
end 

http://www.rubydoc.info/gems/pundit#Policies

+0

返事をありがとう。あなたが説明したようにcurrent_userを提供するカスタム認証レイヤーを用意していますので、技術的には無しのユーザーをテストする必要はありません。しかし、上で与えられた雷雲の実験室で与えられた例と、pundit_matcher githubのページでは、それらの例題テストでは無関係な人がいるので、どうやってそれらを動作させるのか理解しようとしています。 – brad

関連する問題