Populate Instance Variable Defined In Parent Controller For Rspec Test

913 views Asked by At

In my ApplicationController, I expose a variable that can be shared by all controllers:

before_filter :expose_group

protected

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

I'm testing my controllers using RSpec, and for some of these tests, I need to be able to set the @user_group to a known value before they are run. How can I set this variable when testing a subclass of ApplicationController?

Note: I need a way to set @user_group for the test. Controlling the return value of expose_group using a stub doesn't help as @user_group will still be nil.

3

There are 3 answers

0
James On BEST ANSWER

I would scrap the instance variable altogether and use helpers instead. Start with something like a GroupsHelper in 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

Then include it in ApplicationController.

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

Now, in spec/support define a helper for your test.

include ApplicationHelper

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

A test could look something like:

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

When you run your test, user_group will return the value determined by the value you already assigned to the cookie object.

This also has the benefit of just calling join_group rather than stubbing LearningGroup all over the place in multiple tests.

2
ventsislaf On

You can stub expose_group method to return what you want.

In your specs:

controller.stub(expose_group: 'what you need')
5
apneadiving On

I'd simply stub the method like:

LearningGroup.should_receive(:find_by_uid).and_return known_value