Подтвердить что ты не робот

Невозможно использовать вспомогательный метод с 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

Я задал аналогичный вопрос здесь, но приступил к работе. Это странное поведение снова проползло, и я хотел бы понять, почему это не работает.

UPDATE: Я обнаружил, что вызов controller.stub!(:current_user).and_return(@user) до helper.stub!(...) является тем, что вызывает это поведение. Это достаточно легко зафиксировать в spec/support/authentication.rb, но является ли это ошибкой в ​​Rspec? Я не понимаю, почему ожидается, что он не сможет заглушить метод помощника, если он уже был наложен на контроллер.

4b9b3361

Ответ 1

Попробуй, это сработало для меня:

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, а вторая часть основана на этот ответ.

Ответ 2

Обновление для 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/

Ответ 3

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

Ответ 4

В RSpec 3.5 RSpec, похоже, helper больше не доступен из блока it. (Он даст вам следующее сообщение:

helper недоступен из примера (например, блок it) или из конструкций, которые выполняются в области примера (например, before, let и т.д.). Он доступен только в группе примеров (например, a describe или context).

(Я не могу найти документацию об этом изменении, это все знания, полученные экспериментально).

Ключом к решению этого является знание того, что вспомогательные методы являются методами экземпляра, а для ваших собственных вспомогательных методов это легко сделать:

allow_any_instance_of( SomeHelper ).to receive(:current_user).and_return(user) 

Вот что, наконец, помогло мне

Сноски/Кредит, где кредитная линия:

Ответ 5

Это работало для меня в случае 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