البقاء جافًا أثناء اختبار وحدة التحكم، وهو معتمد عبر CanCan

StackOverflow https://stackoverflow.com/questions/4047085

  •  27-09-2019
  •  | 
  •  

سؤال

أنا أكتب بعض الاختبارات بأثر رجعي، باستخدام RSpec، لمشروع Rails.

أنا أستخدم جوهرة CanCan لتقديم الترخيص.قررت أن أكتب المواصفات التي سيتم اختبارها ability.rb نموذج.ثم انتقلت بعد ذلك لاختبار نماذجي المتبقية.

لقد انتقلت إلى وحدات التحكم، ولقد واجهت مشكلة كبيرة:أنا أختبر قدراتي من جديد!

في الأساس، لا بد لي من استبعاد سلسلة من النماذج، وإلغاء ارتباطاتها؛وإلا فإن الرد يعود فقط 403 Forbidden.
والسبب في ذلك هو أن وحدة التحكم هي المسؤولة بشكل أساسي عن القلق بشأن الترخيص.

لست متأكدًا تمامًا من أين أذهب من هنا.أقوم بإخراج ما يصل إلى 6 نماذج، فقط لكتابة اختبار واحد.أنا يعرف قدرات العمل، وهذا ما ability_spec.rb هو ل.

إذن هذا السؤال ذو شقين حقًا:

  1. هل يجب علي اختبار نموذج القدرة بشكل منفصل؟
  2. هل يجب أن تهتم اختبارات وحدة التحكم بالأذونات المناسبة؟

يحررتتطلب "spec_helper" تشمل Inpistise :: TestHelpers # لإعطاء مواصفاتك الوصول إلى المساعدين

describe TokensController do
  before(:each) do
    @mock_user = User.new(:username => "bob", :email => "user@user.com", :password => "longpassword")
    @mock_user.role = "admin"
    sign_in @mock_user
    #Ability.stub!('can').and_return(true)
  end
  it "should let me see grids/:g_id/tokens index" do
    test_grid = mock_model(Grid)
    test_token = mock_model(Token)
    Grid.stub!(:find).and_return(test_grid)
    Token.stub!(:find).and_return(test_token)
    get 'index'

    a1 = Ability.new(@mock_user)
    a1.can?(:index, Token).should be_true # This line works fine; as it should
    puts response.status #This returns 403, which means CanCan::AccessDenied was raised
  end
end

شكرًا،
روبي

هل كانت مفيدة؟

المحلول

أقوم باختبار نموذج Cancan بشكل منفصل ، لكن اختبار ما سيسمح به في أي الظروف.

أعتقد أنه إذا كنت تفعل أشياء مثل

authorize! :take_over, @the_world

ثم أعتقد أنك يجب أن تختبر ذلك في وحدة التحكم. لست متأكدًا من أنك بحاجة إلى اختبار جميع الإصدارات الستة من النماذج الخاصة بك.

يمكنك التخلص من القدرة. الفصل وجعله يستجيب صحيح/خطأ ، واختبر كيفية معالجة وحدة التحكم الخاصة بك عندما يمكن (والأهم من ذلك) عندما لا يمكن الاستمرار.

نصائح أخرى

لست متأكدًا مما إذا كان هذا قد فات الأوان بالنسبة لك ، لكنني واجهت نفس المشكلة ، وحلها باستخدام عينة الكود التالية -

before do
  @user = Factory.create(:user)
    sign_in @user

    @abilities = Ability.new(@user)
    Ability.stub(:new).and_return(@abilities)
  end
end

لقد قمت بإعداد القدرة#جديدة ، مما أعطاني إشارة إلى مثيل القدرة التي تتحكم في المستخدم الحالي. ثم ، يمكنني أن أخرج قدرات محددة مثل هذا:

@abilities.stub!(:can?).with(:destroy, regatta).and_return(true)

أو إعطاء امتيازات المسؤول:

@abilities.stub!(:can?).and_return(false)

على غرار إجابة سام ، ولكن من صفحة كانكان ويكي على الاختبار:

اختبار تحكم

إذا كنت ترغب في اختبار وظائف التفويض على خيار وحدة التحكم في المستوى الأول ، فهو تسجيل الدخول إلى المستخدم الذي لديه الأذونات المناسبة.

user = User.create!(:admin => true) # I recommend a factory for this
# log in user however you like, alternatively stub `current_user` method
session[:user_id] = user.id 
get :index
assert_template :index # render the template since he should have access

بدلاً من ذلك ، إذا كنت ترغب في اختبار سلوك وحدة التحكم بشكل مستقل عن ما هو داخل فئة القدرة ، فمن السهل التخلص من القدرة على أي سلوك تريده.

def setup
  @ability = Object.new
  @ability.extend(CanCan::Ability)
  @controller.stubs(:current_ability).returns(@ability)
end

test "render index if have read ability on project" do
  @ability.can :read, Project
  get :index
  assert_template :index
end

إذا كان لديك أذونات معقدة للغاية ، فقد يؤدي ذلك إلى العديد من الاحتمالات المتفرعة. إذا تم اختبار كل هذه في طبقة وحدة التحكم ، فقد يؤدي ذلك إلى اختبارات بطيئة ومتضخمة. بدلاً من ذلك ، أوصي بإبقاء اختبارات ترخيص وحدة التحكم الضوء واختبار وظيفة التفويض بشكل أكثر شمولاً في نموذج القدرة من خلال اختبارات الوحدة كما هو موضح في الأعلى.

أعتقد أنه يجب إجراء التفويض بشكل أساسي وحدات التحكم للتأكد من أن ترخيصك يعمل بشكل صحيح مع وحدات التحكم الخاصة بك. لجعله جاف يمكنك تنفيذ خاصتك matcher لاستخدام مثل هذا

let!(:user) {create :user}
before { login_user_request user}

it "grants admin access to show action" do
  expect{ get :show, {id: user.id} }.to be_authorized
end
it "denies user access to edit action" do
  expect{ get :edit, {id: user.id} }.to be_un_authorized
end

ثم قم بتنفيذ هذه المطاعم بطريقتك الخاصة لاختبار كيفية تفويض الطلب أم لا

RSpec::Matchers.define :be_authorized do
  match do |block|
    block.call
    expect(response).to be_success
  end

  def supports_block_expectations?
    true
  end
end

RSpec::Matchers.define :be_un_authorized do
  match do |block|
    expect{
      block.call
    }.to raise_error(Pundit::NotAuthorizedError)
  end

  def supports_block_expectations?
    true
  end
end

لماذا لا تدرج أ

can :manage, :all do
  user.is_ultrasuper == 1
end

في قدرتك ثم احصل على معلمة is_ultrasuper في أحد مستخدمي التركيبات لديك:

one: 
  id: 1 
  username: my_username 
  is_ultrasuper: 1

ثم قم بتسجيل دخول هذا المستخدم عند إعداد اختباراتك.هذا في الاختبارات يجب أن تكون قادرًا على فعل أي شيء على الإطلاق.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top