0

在我的ApplicationController,我公开可以由所有控制器共享的变量:填充实例变量定义在父控制器对于Rspec的测试

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

回答

1

我会完全取消实例变量,并使用助手来代替。从开始,类似于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 

然后includeApplicationController

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全部覆盖。

0

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

在您的规格:

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

但它只是隐式返回任何东西。这不是我需要控制的'expose_group'的返回值,而是实例变量。 – Undistraction

+0

在这种情况下,@apneadiving的答案就是您所需要的。 – ventsislaf

1

我只是存根,如方法:

LearningGroup.should_receive(:find_by_uid).and_return known_value 
+0

这只允许我控制'expose_group'的返回值,但我需要的是填充'@ leaning_group'实例变量的方法。 – Undistraction

+0

这个变量在哪里定义? – apneadiving

+0

它在'expose_group'方法中定义在那里。它在ApplicationController中被定义,并在我正在测试的子类中使用。 – Undistraction

相关问题