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

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... Любые предложения?

4b9b3361

Ответ 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.