我有控制器:
class AccountController < ApplicationController
def index
end
private
def current_account
@current_account ||= current_user.account
end
end
如何使用rspec测试私有方法current_account
?
P.S。我使用Rspec2和Ruby on Rails 3
答案 0 :(得分:190)
使用#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
答案 1 :(得分:37)
我使用send方法。例如:
event.send(:private_method).should == 2
因为“发送”可以调用私有方法
答案 2 :(得分:23)
使用current_account方法在哪里?它有什么用途?
通常,您不测试私有方法,而是测试调用私有方法的方法。
答案 3 :(得分:8)
你应该不直接测试你的私人方法,他们可以而且应该通过运用公共方法的代码间接测试。
这使您可以在不改变测试的情况下更改代码的内部结构。
答案 4 :(得分:4)
您可以将私有或受保护的方法设为public:
MyClass.send(:public, *MyClass.protected_instance_methods)
MyClass.send(:public, *MyClass.private_instance_methods)
只需将此代码放在测试类中,替换您的类名。如果适用,请包括命名空间。
答案 5 :(得分: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
答案 6 :(得分:1)
如果需要测试私有函数,请创建一个调用私有函数的公共方法。
答案 7 :(得分: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
答案 8 :(得分:1)
使用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
答案 9 :(得分:0)
我知道这有点像hacky,但是如果你想要通过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