আরএসপেক, রেলস: কন্ট্রোলারদের ব্যক্তিগত পদ্ধতি কীভাবে পরীক্ষা করতে হবে?


125

আমার নিয়ামক রয়েছে:

class AccountController < ApplicationController
  def index
  end

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

current_accountআরএসপেক দিয়ে কীভাবে ব্যক্তিগত পদ্ধতি পরীক্ষা করবেন ?

পিএস আমি আরএসপেক 2 এবং রুবেলটি রিয়েল 3 এ ব্যবহার করি


8
এটি আপনার প্রশ্নের উত্তর দেয় না, তবে ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করার কথা নয়। আপনার পরীক্ষাগুলি কেবল আসল জিনিস - আপনার সর্বজনীন এপিআই সম্পর্কে যত্নশীল হওয়া উচিত । যদি আপনার সর্বজনীন পদ্ধতিগুলি কাজ করে, তবে তারা যে ব্যক্তিগতকৃত কলগুলি সেগুলিও কাজ করে।
স্যামি ডিন্ডে

77
আমি একমত নই আপনার কোডে কোনও জটিল জটিল বৈশিষ্ট্য পরীক্ষা করার মান রয়েছে।
হোয়াইটহ্যাট 101

11
আমিও একমত না। যদি আপনার সর্বজনীন এপিআই কাজ করে তবে আপনি কেবল ধরে নিতে পারেন আপনার ব্যক্তিগত পদ্ধতিগুলি প্রত্যাশার মতো কাজ করছে। তবে আপনার চশমাগুলি কাকতালীয়ভাবে চলে যেতে পারে।
রিমিয়ান

4
কোনও ব্যক্তিগত ক্লাসে পরীক্ষার প্রয়োজন হয় এমন একটি নতুন ক্লাসে প্রাইভেট পদ্ধতিটি উত্তোলন করা ভাল।
ক্রিস

10
@ রনলগ আপনি ঠিক বলেছেন আরও অন্তর্দৃষ্টি এবং অভিজ্ঞতার সাথে, আমি আমার তিন বছরের পুরানো মন্তব্যের সাথে একমত নই। :)
সামি দিনদানে

উত্তর:


196

# ইনস্ট্যান্স_ইভাল ব্যবহার করুন

@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

94
আপনি যদি পছন্দ করেন তবে আপনি এটিও বলতে পারেন: @ কন্ট্রোলআরসেন্ড (: কারেন্ট_অ্যাকউন্ট)।
বিভ্রান্তি

13
রুবি আপনাকে প্রেরণের মাধ্যমে ব্যক্তিগত পদ্ধতিতে কল করতে দেয়, তবে এর অর্থ এই নয় যে আপনার উচিত। ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করে সেই পদ্ধতিগুলিতে পাবলিক ইন্টারফেস পরীক্ষার মাধ্যমে করা হয়। এই পদ্ধতির কাজ করবে, তবে এটি আদর্শ নয়। যদি পদ্ধতিটি এমন কোনও মডিউলে থাকে যা নিয়ামকের অন্তর্ভুক্ত থাকে তবে এটি আরও ভাল। তারপরে এটি নিয়ামকের স্বাধীনভাবেও পরীক্ষা করা যেতে পারে।
ব্রায়ান হোগান

9
তবুও, এই উত্তরটি প্রযুক্তিগতভাবে প্রশ্নের উত্তর দেয়, আমি এটি হ্রাস করছি, কারণ এটি পরীক্ষার সেরা অনুশীলনগুলি লঙ্ঘন করে। ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করা উচিত নয় এবং কেবল যে রুবি আপনাকে পদ্ধতির দৃশ্যমানতা দূরে রাখার ক্ষমতা দেয়, এর অর্থ এই নয় যে আপনার এটির অপব্যবহার করা উচিত।
সর্দজান পেজিক 21 '15

24
Srdjan Pejic আপনি ব্যক্তিগত পদ্ধতি কেন পরীক্ষা করা উচিত নয় তা ব্যাখ্যা করতে পারেন?
জন বাচির

35
আমি মনে করি আপনি উত্তরগুলি ভুল বলে চিহ্নিত করেছেন বা প্রশ্নের উত্তর দিচ্ছেন না। এই উত্তরটি সঠিক এবং নিম্নোক্ত হওয়া উচিত নয়। আপনি যদি ব্যক্তিগত পদ্ধতি পরীক্ষা করার অভ্যাসের সাথে একমত নন তবে মন্তব্যগুলিতে এটি ভাল তথ্য হিসাবে (যেমন অনেকে করেছেন) রাখুন এবং তারপরে লোকেরা সেই মন্তব্যটিকে উজ্জীবিত করতে পারে, যা এখনও আপনার বক্তব্যকে অকারণে একটি প্রাকৃতিক বৈধ উত্তরের চেয়ে কম করে দেখায়।
ট্র্যাডে

37

আমি সেন্ড পদ্ধতি ব্যবহার করি। উদাহরণ:

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

কারণ "প্রেরণ" ব্যক্তিগত পদ্ধতিতে কল করতে পারে


আপনি কীভাবে ব্যক্তিগত পদ্ধতি ব্যবহার করে উদাহরণের ভেরিয়েবলগুলি পরীক্ষা করবেন .send?
12

23

বর্তমান_শক্তি পদ্ধতিটি কোথায় ব্যবহৃত হচ্ছে? এটা কি উদ্দেশ্য পরিবেশন করে?

সাধারণত, আপনি ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করেন না বরং সেই পদ্ধতিগুলি পরীক্ষা করেন যা ব্যক্তিগতকে কল করে।


5
আদর্শভাবে প্রতিটি পদ্ধতি পরীক্ষা করা উচিত। আমি আরএসপি-তে অনেক সাফল্যের সাথে সাবজেক্ট.সেন্ড এবং সাবজেক্ট ইন্ডাস্ট্যানস_এভাল উভয়ই ব্যবহার করেছি
ডেভিড ডব্লু। কিথ

7
@ পুললেটগুলি আমি অসম্মতি জানাই, আপনি আমার এপিআইয়ের সর্বজনীন পদ্ধতি যাচাই করা উচিত যা আমার ব্যক্তিগত উত্তর হিসাবে যেমনটি ব্যক্তিগতকে ডাকবে। আপনি যে API সরবরাহ করেন তা পরীক্ষা করা উচিত, কেবলমাত্র ব্যক্তিগত পদ্ধতিগুলিই আপনি দেখতে পারবেন না।
রায়ান বিগ

5
আমি @ রায়ান বিগের সাথে একমত আপনি ব্যক্তিগত পদ্ধতি পরীক্ষা করেন না। এটি আপনার পরিবর্তনের কোডটি পাবলিক অংশগুলিকে প্রভাবিত করে না, এমনকি যদি সেই পদ্ধতির প্রয়োগটি পরিবর্তন করতে বা পরিবর্তন করতে পারে আপনার ক্ষমতা সরিয়ে দেয়। স্বয়ংক্রিয় পরীক্ষাগুলি লেখার সময় দয়া করে সেরা অনুশীলনগুলি পড়ুন।
সর্দজান পেজিক 21 '13

4
হুম, আমি কিছু মিস করছি। আমি যে ক্লাসগুলি লিখি তাতে জনসাধারণের চেয়ে অনেক বেশি ব্যক্তিগত পদ্ধতি ছিল। কেবলমাত্র পাবলিক এপিআইয়ের মাধ্যমে পরীক্ষার ফলে শত শত টেস্টগুলির একটি তালিকা তৈরি হবে যা তারা পরীক্ষিত কোডটি মিরর করে না।
ডেভিড ডব্লিউ। কিথ

9
আমার বোঝার অনুসারে আপনি যদি ইউনিট পরীক্ষায় ব্যক্তিগত পদ্ধতিতে সত্যিকারের গ্রানুলারিটি অর্জন করতে চান তবে এটিও পরীক্ষা করা উচিত। আপনি যদি রিফ্যাক্টর করতে চান কোড ইউনিট পরীক্ষাও সেই অনুযায়ী রিফ্যাক্টর করতে হবে। এটি আশ্বাস দেয় যে আপনার নতুন কোডটিও প্রত্যাশার মতো কাজ করে।
ইন্দিকা কে

7

আপনার সরাসরি আপনার ব্যক্তিগত পদ্ধতি পরীক্ষা করা উচিত নয় , পাবলিক পদ্ধতি থেকে কোডটি অনুশীলন করে সেগুলি পরোক্ষভাবে পরীক্ষা করা যেতে পারে এবং করা উচিত।

এটি আপনাকে পরীক্ষার পরিবর্তন না করেই আপনার কোডের অভ্যন্তরীণ রাস্তায় নামিয়ে আনতে দেয়।


4

আপনি আপনাকে ব্যক্তিগত বা সুরক্ষিত পদ্ধতিগুলি জনসাধারণ হিসাবে তৈরি করতে পারেন:

MyClass.send(:public, *MyClass.protected_instance_methods) 
MyClass.send(:public, *MyClass.private_instance_methods)

কেবলমাত্র এই কোডটি আপনার পরীক্ষার শ্রেণিতে আপনার শ্রেণীর নাম স্থাপন করুন। প্রযোজ্য ক্ষেত্রে নামস্থান অন্তর্ভুক্ত করুন।


3
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

1

ইউনিট টেস্টিং ব্যক্তিগত পদ্ধতি প্রয়োগের আচরণের সাথে প্রসঙ্গের বাইরে খুব বেশি।

আপনি কি প্রথমে আপনার কলিং কোডটি লিখছেন? এই কোডটি আপনার উদাহরণে বলা হয় না।

আচরণটি হ'ল: আপনি অন্য একটি বস্তু থেকে বোঝা একটি জিনিস চান।

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


1

প্রসঙ্গের মধ্যে অস্থায়ীভাবে ব্যক্তিগত পদ্ধতিগুলি সর্বজনীন করতে আরএসপেক-প্রসঙ্গ-ব্যক্তিগত রত্ন ব্যবহার করুন ।

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

0

আপনার যদি কোনও ব্যক্তিগত ফাংশন পরীক্ষা করতে হয় তবে একটি সর্বজনীন পদ্ধতি তৈরি করুন যা ব্যক্তিগতটিকে অনুরোধ করে।


3
আমি ধরে নিলাম আপনার অর্থ এই যে এটি আপনার ইউনিট পরীক্ষার কোডে করা উচিত। এটাই মূলত .instance_eval এবং .send কোডের একক লাইনে করে। (এবং একটি সংক্ষিপ্ততর একই প্রভাব ফেললে কে আর দীর্ঘতর পরীক্ষা লিখতে চায়?)
ডেভিড ডব্লু। কিথ

3
দীর্ঘশ্বাস ফেলুন, এটি একটি রেল নিয়ন্ত্রণকারী। পদ্ধতিটি বেসরকারী হতে হবে। আসল প্রশ্নটি পড়ার জন্য ধন্যবাদ।
মাইকেল জনস্টন

আপনি সর্বদা কোনও পরিষেবা অবজেক্টে কোনও সরকারী পদ্ধতিতে ব্যক্তিগত পদ্ধতিটি বিমূর্ত করতে পারেন এবং সেভাবে উল্লেখ করতে পারেন। এইভাবে আপনি কেবল সর্বজনীন পদ্ধতি পরীক্ষা করতে পারেন এবং এখনও আপনার কোডটি ডিআরওয়াই রাখতে পারেন।
জেসন

0

আমি জানি এটি কান্ডা হ্যাকি, তবে আপনি যদি আরএসপেকের মাধ্যমে পরীক্ষামূলক পদ্ধতিগুলি দেখতে চান তবে প্রোডে দৃশ্যমান না হয় তবে এটি কাজ করে।

class Foo
  def public_method
    #some stuff
  end

  eval('private') unless Rails.env == 'test'

  def testable_private_method
    # You can test me if you set RAILS_ENV=test
  end 
end

এখন আপনি যখন চালাতে পারেন আপনি যেমন মত স্পেক:

RAILS_ENV=test bundle exec rspec spec/foo_spec.rb 
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.