Ruby on rails 无法使用rspec来存根帮助器方法

Ruby on rails 无法使用rspec来存根帮助器方法,ruby-on-rails,ruby-on-rails-3,rspec,rspec2,rspec-rails,Ruby On Rails,Ruby On Rails 3,Rspec,Rspec2,Rspec Rails,我试图在控制器中定义的助手上存根一个方法。例如: 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_

我试图在控制器中定义的助手上存根一个方法。例如:

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
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
我问了一个类似的问题,但最终还是找到了解决办法。这种奇怪的行为又一次出现了,我想知道为什么这不起作用


更新:我发现调用
controller.stub!(:当前用户)和返回(@user)
helper.stub之前!(…)
是导致这种行为的原因。这很容易在
spec/support/authentication.rb中修复,但这是Rspec中的一个bug吗?我不明白,如果一个方法已经在控制器上存根,为什么它不能在助手上存根呢。

试试这个,它对我有用:

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的作者,第二部分基于。

更新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到
存根的方法将是:

allow(helper).接收(:current_user){user}

参见:

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")

在rspec3.5rspec中,似乎不再可以从
it
块访问
helper
。(它将向您提供以下信息:

helper
在示例(例如
it
块)内或在示例范围内运行的构造(例如
before
let
等)中不可用。它仅在示例组(例如
description
context
块)上可用

(我似乎找不到关于这一变化的任何文件,这都是通过实验获得的知识)

解决这个问题的关键是要知道helper方法是实例方法,并且对于您自己的helper方法,很容易做到这一点:

allow_any_instance_of( SomeHelper ).to receive(:current_user).and_return(user) 
这就是我最终的工作

脚注/信贷到期时的信贷:


在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

请尝试通过ApplicationController对该方法进行存根,因为它是在ApplicationController中定义的。
ApplicationController.stub(:current\u user=>@user)
EDIT:现在我认为这可能不起作用。不,它不起作用。我也尝试了
任何实例
,但运气不佳。我实际上已经让它起作用了,但我有点困惑(可能在rspec中发现了一个bug)。我将很快更新这个问题。听起来像个bug。它绝对值得在上提交一个问题(并尝试使用最新版本).Created ticket:我也有同样的问题,是否有任何解决方案?…然后测试实际上需要测试@helper,而不是SomeHelper。我修复了RSpec 3的答案。非常聪明。首先定义缺少的方法(从另一个助手,控制器)在您的帮助程序中,然后存根。
def…
块是否可以直接使用
用户
,因此不需要存根?
let(:user) { create :user }
helper do
  def current_user; end
end
before do
  allow(helper).to receive(:current_user).and_return user
end