Невозможно использовать вспомогательный метод с 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? Я не понимаю, почему ожидается, что он не сможет заглушить метод помощника, если он уже был наложен на контроллер.
Ответы
Ответ 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