无法使用rspec进行存根辅助方法

Bra*_*rad 22 rspec ruby-on-rails rspec2 rspec-rails ruby-on-rails-3

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

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
Run Code Online (Sandbox Code Playgroud)

在我的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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

在这里问了一个类似的问题,但最终解决了一个问题.这种奇怪的行为再次崛起,我想了解为什么这不起作用.

更新:我发现controller.stub!(:current_user).and_return(@user)之前调用helper.stub!(...)是导致此行为的原因.这很容易修复spec/support/authentication.rb,但这是Rspec中的一个错误吗?我不明白为什么如果它已经存在于控制器上,它将无法在助手上存根方法.

d_r*_*ail 20

更新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
Run Code Online (Sandbox Code Playgroud)

编辑.RSpec 3的方式stub!是:

allow(helper).to receive(:current_user) { user }

请参阅:https : //relishapp.com/rspec/rspec-mocks/v/3-2/docs/


Mat*_*off 8

试试这个,它对我有用:

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
Run Code Online (Sandbox Code Playgroud)

第一部分是基于RSpec作者的回复,第二部分是基于Stack Overflow的回答.


Alb*_*ing 5

规格 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")
Run Code Online (Sandbox Code Playgroud)


Rya*_*cox 5

在RSpec 3.5 RSpec中,似乎helper不再可以从it块进行访问。(它将给您以下消息:

helper不能从一个示例(例如,内it块),或从该构建体中的示例的范围的运行(例如beforelet等)。它仅在示例组(例如a describecontextblock)上可用。

(我似乎找不到有关此更改的任何文档,这些都是通过实验获得的所有知识)。

解决此问题的关键是要知道辅助方法是实例方法,而对于您自己的辅助方法而言,这样做很容易:

allow_any_instance_of( SomeHelper ).to receive(:current_user).and_return(user) 
Run Code Online (Sandbox Code Playgroud)

这终于对我有用

脚注/信用额度: