Ruby-on-rails 无法使用 rspec 存根辅助方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10537932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unable to stub helper method with rspec
提问by Brad
I am trying to stub a method on a helper that is defined in my controller. For example:
我试图在我的控制器中定义的帮助程序上存根一个方法。例如:
class ApplicationController < ActionController::Base
def current_user
@current_user ||= authenticated_user_method
end
helper_method :current_user
end
module SomeHelper
def do_something
current_user.call_a_method
end
end
In my Rspec:
在我的 Rspec 中:
describe SomeHelper
it "why cant i stub a helper method?!" do
helper.stub!(:current_user).and_return(@user)
helper.respond_to?(:current_user).should be_true # Fails
helper.do_something # Fails 'no method current_user'
end
end
In spec/support/authentication.rb
在 spec/support/authentication.rb
module RspecAuthentication
def sign_in(user)
controller.stub!(:current_user).and_return(user)
controller.stub!(:authenticate!).and_return(true)
helper.stub(:current_user).and_return(user) if respond_to?(:helper)
end
end
RSpec.configure do |config|
config.include RspecAuthentication, :type => :controller
config.include RspecAuthentication, :type => :view
config.include RspecAuthentication, :type => :helper
end
I asked a similar question here, but settled on a work around. This strange behavior has creeped up again and I would like to understand whythis doesnt work.
我在这里问了一个类似的问题,但决定解决。这种奇怪的行为再次出现,我想了解为什么这不起作用。
UPDATE: I have found that calling controller.stub!(:current_user).and_return(@user)before helper.stub!(...)is what is causing this behavior. This is easy enough to fix in spec/support/authentication.rb, but is this a bug in Rspec? I dont see why it would be expected to not be able to stub a method on a helper if it was already stubbed on a controller.
更新:我发现controller.stub!(:current_user).and_return(@user)之前调用helper.stub!(...)是导致这种行为的原因。这很容易修复spec/support/authentication.rb,但这是 Rspec 中的错误吗?我不明白为什么如果它已经在控制器上存根,为什么它不能存根帮助器上的方法。
采纳答案by Matthew Ratzloff
Try this, it worked for me:
试试这个,它对我有用:
describe SomeHelper
before :each do
@helper = Object.new.extend SomeHelper
end
it "why cant i stub a helper method?!" do
@helper.stub!(:current_user).and_return(@user)
# ...
end
end
The first part is based on this replyby the author of RSpec, and the second part is based on this Stack Overflow answer.
第一部分基于RSpec作者的这个回复,第二部分基于这个Stack Overflow的回复。
回答by d_rail
Update to Matthew Ratzloff's answer: You don't need the instance object and stub! has been deprecated
更新 Matthew Ratzloff 的回答:您不需要实例对象和存根!已被弃用
it "why can't I stub a helper method?!" do
helper.stub(:current_user) { user }
expect(helper.do_something).to eq 'something'
end
Edit. The RSpec 3 way to stub!would be:
编辑。RSpec 3 的方法stub!是:
allow(helper).to receive(:current_user) { user }
allow(helper).to receive(:current_user) { user }
回答by RyanWilcox
In RSpec 3.5 RSpec, it seems like helperis no longer accessible from an itblock. (It will give you the following message:
在 RSpec 3.5 RSpec 中,似乎helper不再可以从it块访问。(它会给你以下信息:
helperis not available from within an example (e.g. anitblock) or from constructs that run in the scope of an example (e.g.before,let, etc). It is only available on an example group (e.g. adescribeorcontextblock).
helper不能从一个示例(例如,内it块),或从该构建体中的示例的范围的运行(例如before,let等)。它仅适用于示例组(例如 adescribe或context块)。
(I can't seem to find any documentation on this change, this is all knowledge gained experimentally).
(我似乎找不到有关此更改的任何文档,这是通过实验获得的所有知识)。
The key to solving this is knowing that helper methods are instance methods, and that for your own helper methods it's easy to do this:
解决这个问题的关键是知道辅助方法是实例方法,对于你自己的辅助方法,很容易做到这一点:
allow_any_instance_of( SomeHelper ).to receive(:current_user).and_return(user)
This is what finally worked for me
这最终对我有用
Footnotes/Credit Where Credit Due:
脚注/信用到期时:
回答by Albert.Qing
Rspec 3
规格 3
user = double(image: urlurl)
allow(helper).to receive(:current_user).and_return(user)
expect(helper.get_user_header).to eq("/uploads/user/1/logo.png")
回答by Samuel
This worked for me in the case of RSpec 3:
在 RSpec 3 的情况下,这对我有用:
let(:user) { create :user }
helper do
def current_user; end
end
before do
allow(helper).to receive(:current_user).and_return user
end

