Rails Pundit Policy Spec测试失败,出现NoMethodError

时间:2016-08-13 10:46:22

标签: ruby-on-rails rspec authorization pundit

我刚开始在当前的项目中使用Pundit进行授权以及权威匹配宝石。

到目前为止,它似乎通常对我有用,但我的测试中存在问题。

我一般都试图按照pundit-matchers readme和Thunderbolt实验室博客(http://thunderboltlabs.com/blog/2013/03/27/testing-pundit-policies-with-rspec/)中的示例进行操作。

这是我的政策文件;

  protected void onActivityResult(
        int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch(requestCode) {

        case REQUEST_ACCOUNT_PICKER:
            if (resultCode == RESULT_OK && data != null &&
                    data.getExtras() != null) {
                String accountName =
                        data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);



                            Log.e("ghfyg",""+accountName);
                if (accountName != null) {
                    mCredential.setSelectedAccountName(accountName);
                    SharedPreferences settings =
                            AccountSync.this.getSharedPreferences("deep",Context.MODE_PRIVATE);
                    SharedPreferences.Editor editor = settings.edit();
                    editor.putString("PREF_ACCOUNT_NAME", accountName);
                    editor.apply();
                }
            } else if (resultCode == RESULT_CANCELED) {
                Toast.makeText(this,"Account unspecified.",Toast.LENGTH_SHORT).show();
            }
            break;

    }

    super.onActivityResult(requestCode, resultCode, data);
}

这是我的policy_spec文件

#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次测试中有2次通过; 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 "for a non-admin user"个。 "for an admin user"测试失败,

"for a guest"

现在我明白了为什么。我将NoMethodError: undefined method `admin?' for nil:NilClass 传递给了我的ProcedurePolicy类的nil方法,该方法没有#index?方法。但我在网上找到的所有示例规范都是这样做的。我没看到什么。

如果我错过了一些非常明显的东西,我会道歉。我已经远离编码几年了。

1 个答案:

答案 0 :(得分:1)

"作为访客" context用于在系统中当前没有用户进行身份验证时测试授权尝试。由于没有用户登录,因此不存在用户记录/对象 - 用户对象的缺席nil。这就是Thunderbolt Labs和pundit-matchers示例使用nil来代表访问者的原因。 nil对象没有admin?方法,导致错误。

要在策略中正确处理nil / guest用户,请在检查用户是否为admin之前检查用户对象是否存在,方法是直接检查用户对象或使用Rails中的present?方法,例如

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

或只是:

def index?
  user && user.admin?
end

当没有用户登录时,您会发现诸如Devise之类的身份验证系统从nil方法返回current_user