0

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 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

I'd simply stub the method like:

LearningGroup.should_receive(:find_by_uid).and_return known_value

5 Comments

This would only allow me to control the return value of expose_group, but what I need is a way to populate the @leaning_group instance variable.
where is this variable defined?
It's defined right there in the expose_group method. It's defined there in the ApplicationController and used in the subclass that I'm testing.
you define @user_group there. the variable will be set with your known value if the before filter is executed. If it's not the should_receive will let you know
Sorry. I've got you. Thanks.
0

You can stub expose_group method to return what you want.

In your specs:

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

2 Comments

But it's only returning anything implicitly. It's not the return value of expose_group that I need to control, but the instance variable.
In this case the answer of @apneadiving is what you need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.