无法使用rspec存储辅助方法
我试图在我的控制器中定义的助手上存根方法。 例如:
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
在我的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
在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
我在这里问了一个类似的问题,但最终解决了一个问题。 这种奇怪的行为再次崛起,我想了解为什么这不起作用。
更新 :我发现在helper.stub!(...)
之前调用controller.stub!(:current_user).and_return(@user)
是导致此行为的原因。 这很容易修复spec/support/authentication.rb
,但这是Rspec中的一个错误吗? 我不明白为什么如果它已经存在于控制器上,那么它将无法在助手上存根方法。
试试这个,它对我有用:
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
第一部分基于RSpec作者的回复 ,第二部分基于Stack Overflow的回答 。
更新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
编辑。 RSpec 3方式stub!
将会:
allow(helper).to receive(:current_user) { user }
请参阅: https : //relishapp.com/rspec/rspec-mocks/v/3-2/docs/
Rspec 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")
在RSpec 3.5 RSpec中,似乎无法从it
块访问helper
程序。 (它会给你以下信息:
helper
在示例(例如it
块)中或从在示例范围内运行的构造(例如before
,let
等)中不可用。 它仅适用于示例组(例如,describe
或context
块)。
(我似乎无法找到有关此更改的任何文档,这是通过实验获得的所有知识)。
解决这个问题的关键是知道帮助器方法是实例方法,而对于你自己的帮助器方法,它很容易做到这一点:
allow_any_instance_of( SomeHelper ).to receive(:current_user).and_return(user)
这是最终为我工作的
脚注/信用到期信用:
- 超级道具由Johnny Ji撰写的一篇关于他们在帮助/实例方法中挣扎的博客文章
在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