Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing session from a helper spec in rspec

I have a method in my ApplicationHelper that checks to see if there are any items in my basket

module ApplicationHelper
  def has_basket_items?
    basket = Basket.find(session[:basket_id])
    basket ? !basket.basket_items.empty? : false
  end
end

Here is my helper spec that I have to test this:

require 'spec_helper'

describe ApplicationHelper do
  describe 'has_basket_items?' do
    describe 'with no basket' do

      it "should return false" do
        helper.has_basket_items?.should be_false
      end

    end
  end
end

however when I run the test i get

SystemStackError: stack level too deep
/home/user/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.8/lib/action_dispatch/testing/test_process.rb:13:

From debugging this i see that session is being accessed in ActionDispatch::TestProcess from @request.session, and @request is nil. When i access the session from my request specs @request is an instance of ActionController::TestRequest.

My question is can I access the session object from a helper spec? If I can, how? And if I cant what is the best practice to test this method?

****UPDATE****

This was down to having include ActionDispatch::TestProcess in my factories. Removing this include sorts the problem.

like image 204
Dave Oh Avatar asked Dec 02 '12 20:12

Dave Oh


2 Answers

can I access the session object from a helper spec?

Yes.

module ApplicationHelper
  def has_basket_items?
    raise session.inspect
    basket = Basket.find(session[:basket_id])
    basket ? !basket.basket_items.empty? : false
  end
end

$ rspec spec/helpers/application_helper.rb

Failure/Error: helper.has_basket_items?.should be_false
  RuntimeError:
    {}

The session object is there and returns an empty hash.

Try reviewing the backtrace in more detail to find the error. stack level too deep usually indicates recursion gone awry.

like image 170
zetetic Avatar answered Nov 10 '22 00:11

zetetic


You are testing has_basket_items? action in ApplicationHelper, which check a specfic basket with a basket_id in the baskets table, so you should have some basket objects in your test which you can create using Factory_Girl gem.

Hers's an example :-

basket1 = Factory(:basket, :name => 'basket_1')
basket2 = Factory(:basket, :name => 'basket_2')

You can get more details on How to use factory_girl from this screen cast http://railscasts.com/episodes/158-factories-not-fixtures

It will create a Factory object in your test database. So, basically you can create some factory objects and then set a basket_id in session to check for its existence like this :

session[:basket_id] = basket1.id

So, your test should be like this :-

require 'spec_helper'

describe ApplicationHelper do
  describe 'has_basket_items?' do
    describe 'with no basket' do

      it "should return false" do
        basket1 = Factory(:basket, :name => 'basket_1')
        basket2 = Factory(:basket, :name => 'basket_2')
        session[:basket_id] = 1234 # a random basket_id 
        helper.has_basket_items?.should be_false
      end

    end
  end
end

Alternatively, you can check for a basket_id which is being created by factory_girl to be_true by using :

session[:basket_id] = basket1.id
helper.has_basket_items?.should be_true
like image 23
Amit Thawait Avatar answered Nov 09 '22 22:11

Amit Thawait