RSpec и защищенные методы, спецификация контроллера для current_user
Возможно, я ошибаюсь. Сначала я делаю спецификацию, BDD/TDD и нажимаю удар.
У меня есть этот application_controller_spec.rb
require "spec_helper"
describe ApplicationController do
describe "current_user" do
it "should return nil if no one is logged in" do
subject.current_user.should be_nil
end
it "should return currently logged in user" do
hash = {user_id: "my_id"}
subject.should_receive(:session).and_return hash
subject.current_user.should == "my_id"
end
end
end
который отлично работает без ключевого слова protected
.
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_user
protected
def current_user
session[:user_id]
end
end
с включен protected
, я получаю эту ошибку msg
NoMethodError: protected method `current_user' called for #<ApplicationController:0x2a90888>
Я должен быть в состоянии проверить с помощью helper_method... Любые предложения?
Ответы
Ответ 1
helper_method
делает метод доступным в представлениях, а не в контроллере, в соответствии с документами.
Если вам действительно нужен доступ к методу из спецификации контроллера, вы можете использовать send
:
subject.send(:current_user).should be_nil
Но вы, возможно, захотите рассмотреть вопрос о том, имеет ли смысл тестирование методы, не относящиеся к публике, или если было бы лучше проверить использование спецификаций вида. Или необходимо, чтобы этот метод был защищен в первую очередь. Также может быть поучительным понять, как Devise и Authlogic проводят тестирование для своих методов current_user
.
Ответ 2
Хотя прошло довольно много времени с оригинального вопроса, возможно, кто-то найдет это полезным.
Вы можете сделать анонимный подкласс ApplicationController
и открыть внутри него защищенные методы. Нет необходимости в методе send()
.
Вот как это сделать:
describe ApplicationController, type: :controller do
controller do
def current_user
super
end
end
...
it 'should return nil if no one is logged in' do
expect(controller.current_user).to be_nil # (or whatever)
end
end
Источник этот ответ SO.