使用RSpec测试@current_user方法

时间:2011-04-01 16:41:27

标签: ruby unit-testing rspec authlogic

我一直试图这样做几天,但我无法弄明白。我的控制器中有以下代码:

@some_object = @current_user.some_method

在我的规范中,我想在该方法上附加一个should_receive挂钩,但我无法使它工作。我已经尝试了所有这些,但它们都不起作用:

assigns[:current_user].should_receive(:some_method).at_least(:once) # expected 1, got 0
User.should_receive(:some_method).at_least(:once) # expected 1, got 0

测试方法的正确方法如何?我在我的规范中运行这个,登录正在运行:

setup :activate_authlogic
...
UserSession.create(users(:rune))

谢谢!

2 个答案:

答案 0 :(得分:5)

一个例子来自Ruby on Rails Tutorial。它不是直接设置和读取@current_user,而是定义了两个辅助方法:

def current_user=(user)
  @current_user = user
end

def current_user
  @current_user
end

稍后,他们使用controller方法在测试中访问此方法:

def test_sign_in(user)
  controller.current_user = user
end

使用此方法,您应该能够使用

controller.current_user.should_receive(:some_method).at_least(:once)

答案 1 :(得分:1)

你不能在控制器中调用类似的东西:

expect(current_user).to be_present
expect(user_signed_in?).to be_true

所以,你可以这样做:

module ControllerMacros
  def current_user
    user_session_info = response.request.env['rack.session']['warden.user.user.key']
    if user_session_info
      user_id = user_session_info[0][0]
      User.find(user_id)
    else
      nil
    end
  end

  def user_signed_in?
    !!current_user
  end
end

您可以将ControllerMacros包含在控制器规范的顶部,也可以将其包含在spec_helper.rb中,如下所示:

RSpec.configure do |config|
  config.include ControllerMacros, type: :controller
end