填充在父控制器中定义的实例变量用于Rspec测试

时间:2013-08-26 13:37:22

标签: ruby-on-rails ruby-on-rails-3 testing rspec applicationcontroller

在我的ApplicationController中,我公开了一个可以被所有控制器共享的变量:

before_filter :expose_group

protected

    # Much simplified
    def expose_group
      @user_group = LearningGroup.find_by_uid(cookies[:user_group])
    end

我正在使用RSpec测试我的控制器,对于其中一些测试,我需要能够在运行之前将@user_group设置为已知值。在测试ApplicationController的子类时如何设置此变量?

注意:我需要一种方法来为测试设置@user_group。使用存根控制expose_group的返回值无效,因为@user_group仍为零。

3 个答案:

答案 0 :(得分:1)

我只是将方法存根如下:

LearningGroup.should_receive(:find_by_uid).and_return known_value

答案 1 :(得分:1)

我会完全废弃实例变量并改为使用帮助器。从GroupsHelper中的app/helpers/groups_helper.rb开始。

module GroupsHelper
  def user_group
    @user_group ||= group_from_cookie
  end

  def user_group=(group)
    @user_group = group
  end

  private

  def group_from_cookie
    group_uid = cookies[:user_group]
    LearningGroup.find_by_uid group_uid unless group_uid.nil?
  end
end

然后include ApplicationController。{/ p>

class ApplicationController < ActionController::Base
  include GroupsHelper
  # ...
end

现在,在spec/support中为您的测试定义一个助手。

include ApplicationHelper

def join_group group_uid
  # whatever preparation you may need to do as well
  cookies[:user_group] = group_uid
end

测试看起来像:

it 'does something awesome' do
  join_group 'my awesome group id'
  # ...
  expect(your_subject).to be_awesome
end

运行测试时,user_group将返回由您已分配给Cookie对象的值确定的值。

这样做的好处是只需调用join_group,而不是在多个测试中遍布LearningGroup

答案 2 :(得分:0)

您可以使用expose_group方法来返回您想要的内容。

在您的规格中:

controller.stub(expose_group: 'what you need')