私はコントローラーを持っています:
class AccountController < ApplicationController
def index
end
private
def current_account
@current_account ||= current_user.account
end
end
プライベートメソッドをテストする方法current_account
rspecで?
追伸Rspec2とRuby on Rails 3
#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
Sendメソッドを使用します。例えば:
event.send(:private_method).should == 2
「送信」はプライベートメソッドを呼び出すことができるため
Current_accountメソッドはどこで使用されていますか?どんな目的に役立ちますか?
通常、プライベートメソッドをテストするのではなく、プライベートメソッドを呼び出すメソッドをテストします。
notプライベートメソッドを直接テストする必要があります。パブリックメソッドからコードを実行することで間接的にテストできます。
これにより、テストを変更することなく、コードの内部を変更できます。
プライベートまたは保護されたメソッドをパブリックとして作成できます。
MyClass.send(:public, *MyClass.protected_instance_methods)
MyClass.send(:public, *MyClass.private_instance_methods)
このコードをテストクラスに配置して、クラス名を置き換えてください。該当する場合、名前空間を含めます。
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-context-private gem を使用して、コンテキスト内でプライベートメソッドを一時的にパブリックにします。
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
私はこれがちょっとハッキーだと知っていますが、rspecでテストできるがprodでは見えないメソッドが必要な場合に機能します。
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
プライベート関数をテストする必要がある場合は、プライベート関数を呼び出すパブリックメソッドを作成します。