【问题标题】:Populate Instance Variable Defined In Parent Controller For Rspec Test填充在父控制器中定义的实例变量以进行 Rspec 测试
【发布时间】:2013-08-26 13:37:22
【问题描述】:

在我的 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 仍然为零。

【问题讨论】:

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


    【解决方案1】:

    我会完全废弃实例变量并使用助手。从app/helpers/groups_helper.rb 中的GroupsHelper 之类的内容开始。

    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

    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】:

      我只是简单地存根方法,例如:

      LearningGroup.should_receive(:find_by_uid).and_return known_value
      

      【讨论】:

      • 这只会让我控制expose_group的返回值,但我需要的是一种填充@leaning_group实例变量的方法。
      • 这个变量是在哪里定义的?
      • 它是在expose_group 方法中定义的。它在 ApplicationController 中定义并在我正在测试的子类中使用。
      • 你在那里定义@user_group。如果执行之前的过滤器,该变量将设置为您的已知值。如果不是should_receive 会通知您
      • 对不起。我有你。谢谢。
      【解决方案3】:

      你可以存根expose_group方法来返回你想要的。

      在您的规格中:

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

      【讨论】:

      • 但它只是隐式返回任何内容。我需要控制的不是expose_group的返回值,而是实例变量。
      • 在这种情况下,@apneadiving 的答案就是您所需要的。
      猜你喜欢
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多