ruby on rails - Rspec ، القضبان: كيفية اختبار أساليب خاصة من وحدات التحكم؟




ruby-on-rails (7)

أستخدم طريقة الإرسال. على سبيل المثال:

event.send(:private_method).should == 2

لأن "إرسال" يمكن استدعاء أساليب خاصة

لدي جهاز تحكم:

class AccountController < ApplicationController
  def index
  end

  private
  def current_account
    @current_account ||= current_user.account
  end
end

كيف لاختبار طريقة خاصة current_account مع rspec؟

PS يمكنني استخدام Rspec2 وروبي على القضبان 3


أين يتم استخدام طريقة current_account؟ ما الغرض من الخدمة؟

بشكل عام ، لا تختبر الطرق الخاصة بل تختبر الطرق التي تستدعي الطريقة الخاصة.


استخدم #instance_eval

@controller = AccountController.new
@controller.instance_eval{ current_account }   # invoke the private method
@controller.instance_eval{ @current_account }.should eql ... # check the value of the instance variable

استخدم جوهرة rspec-context-private لجعل الطرق الخاصة عامة بشكل عام ضمن السياق.

gem 'rspec-context-private'

وهو يعمل عن طريق إضافة سياق مشترك لمشروعك.

RSpec.shared_context 'private', private: true do

  before :all do
    described_class.class_eval do
      @original_private_instance_methods = private_instance_methods
      public *@original_private_instance_methods
    end
  end

  after :all do
    described_class.class_eval do
      private *@original_private_instance_methods
    end
  end

end

بعد ذلك ، إذا قمت بالمرور :private كبيانات وصفية إلى كتلة describe ، فإن الطرق الخاصة ستكون عامة في هذا السياق.

describe AccountController, :private do
  it 'can test private methods' do
    expect{subject.current_account}.not_to raise_error
  end
end

يبدو اختبار أساليب الوحدة الخاصة بعيدًا عن السياق مع سلوك التطبيق.

هل تكتب رمز الاتصال الخاص بك أولاً؟ لا يسمى هذا الرمز في المثال الخاص بك.

السلوك هو: تريد كائن تم تحميله من كائن آخر.

context "When I am logged in"
  let(:user) { create(:user) }
  before { login_as user }

  context "with an account"
    let(:account) { create(:account) }
    before { user.update_attribute :account_id, account.id }

    context "viewing the list of accounts" do
      before { get :index }

      it "should load the current users account" do
        assigns(:current_account).should == account
      end
    end
  end
end

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

هل يتم استخدام هذا الرمز في الكثير من الأماكن؟ هل تحتاج إلى نهج أكثر عمومية؟

https://www.relishapp.com/rspec/rspec-rails/v/2-8/docs/controller-specs/anonymous-controller


يجب أن لا تختبر طريقتك الخاصة مباشرة ، بل يمكن اختبارها بشكل غير مباشر من خلال ممارسة الرمز من الطرق العامة.

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


require 'spec_helper'

describe AdminsController do 
  it "-current_account should return correct value" do
    class AccountController
      def test_current_account
        current_account           
      end
    end

    account_constroller = AccountController.new
    account_controller.test_current_account.should be_correct             

   end
end




rspec