القضبان والمصادقة المريحة وRSpec - كيفية اختبار النماذج الجديدة التي تتطلب المصادقة

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

سؤال

لقد قمت بإنشاء تطبيق تعليمي باستخدام بورت, ، وهو تطبيق أساسي يتضمن Restful Authentication وRSpec.لقد قمت بتشغيله وأضفت كائنًا جديدًا يتطلب من المستخدمين تسجيل الدخول قبل أن يتمكنوا من فعل أي شيء (before_filter :login_required في وحدة التحكم).[يحرر:ويجب أن أذكر أيضًا أن المستخدم has_many للفئة الجديدة ويجب أن يتمكن المستخدم فقط من رؤيتها.]

لقد قمت بإنشاء النموذج/وحدة التحكم الجديدة باستخدام مولدات Rspec التي أنشأت عددًا من الاختبارات الافتراضية.كلهم يمرون إذا لم يكن هناك before_filter لكن العديد منها يفشل، كما هو متوقع، بمجرد before_filter في مكانه.

كيف يمكنني تشغيل الاختبارات التي تم إنشاؤها كما لو كان هناك/لم يكن هناك مستخدم قام بتسجيل الدخول؟هل أحتاج إلى مجموعة كاملة من المطابقة التي لم يتم تسجيل الدخول إليها - إعادة توجيه الاختبارات؟أفترض أن هذا نوع من أسلوب السخرية أو التثبيت ولكني جديد على RSpec وأنا على غير هدى قليلاً.سيكون موضع تقدير أيضًا الروابط التعليمية الجيدة لـ RSpec.

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

المحلول

لدي إعداد مشابه جدًا، وفيما يلي الكود الذي أستخدمه حاليًا لاختبار هذه الأشياء.في كل من describeلقد وضعت في:

it_should_behave_like "login-required object"
def attempt_access; do_post; end

إذا كان كل ما تحتاجه هو تسجيل الدخول، أو

it_should_behave_like "ownership-required object"
def login_as_object_owner; login_as @product.user; end
def attempt_access; do_put; end
def successful_ownership_access
  response.should redirect_to(product_url(@product))
end

إذا كنت بحاجة إلى الملكية.من الواضح أن الأساليب المساعدة تتغير (قليلًا جدًا) مع كل دورة، ولكن هذا يؤدي معظم العمل نيابةً عنك.هذا موجود في spec_helper.rb الخاص بي

shared_examples_for "login-required object" do
  it "should not be able to access this without logging in" do
    attempt_access

    response.should_not be_success
    respond_to do |format|
      format.html { redirect_to(login_url) }
      format.xml { response.status_code.should == 401 }
    end
  end
end

shared_examples_for "ownership-required object" do
  it_should_behave_like "login-required object"

  it "should not be able to access this without owning it" do
    attempt_access

    response.should_not be_success
    respond_to do |format|
      format.html { response.should be_redirect }
      format.xml { response.status_code.should == 401 }
    end
  end

  it "should be able to access this if you own it" do
    login_as_object_owner
    attempt_access

    if respond_to?(:successful_ownership_access)
      successful_ownership_access
    else
      response.should be_success
    end
  end
end

نصائح أخرى

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

before(:each) do
  controller.stub!(:authenticate).and_return(true)
end

يعمل المثال أعلاه حيث يتم تعيين before_filter الخاص بي على طريقة المصادقة:

before_filter :authenticate

وتستخدم المصادقة في تطبيقي مصادقة HTTP الأساسية، ولكنها يمكن أن تكون أي آلية مصادقة أخرى.

private
def authenticate
  authenticate_or_request_with_http_basic do |user,password|
    user == USER_NAME && password == PASSWORD
  end
end

أعتقد أنها طريقة واضحة ومباشرة للاختبار.

لقد وجدت بعض الإجابات على سؤالي الخاص.في الأساس، كنت بحاجة إلى فهم كيفية الاستهزاء بالمستخدم restful_authentication بحيث يمكن اجتياز اختبارات وحدة التحكم rspec التي تم إنشاؤها تلقائيًا على الرغم من أنني قمت بإضافتها before_filter: login_required.

فيما يلي بعض الموارد التي وجدتها للتو:

المواصفات:ينبغي أن تتصرف مثل

rspec، وrestful_authentication، وlogin_required

باستخدام Restful_authentication current_user داخل مواصفات وحدة التحكم

تجفيف مواصفات RSpecs الخاصة بوحدة التحكم CRUD

للسخرية من مستخدم قام بتسجيل الدخول، قمت باختراق وحدة التحكم لضبطها @current_user يدويا:

module AuthHelper
  protected

  def login_as(model, id_or_attributes = {})
    attributes = id_or_attributes.is_a?(Fixnum) ? {:id => id} : id_or_attributes
    @current_user = stub_model(model, attributes)
    target = controller rescue template
    target.instance_variable_set '@current_user', @current_user

    if block_given?
      yield
      target.instance_variable_set '@current_user', nil
    end
    return @current_user
  end

  def login_as_user(id_or_attributes = {}, &block)
    login_as(User, id_or_attributes, &block)
  end
end
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top