从rspec中的帮助程序规范访问会话

我的ApplicationHelper中有一个方法可以检查我的购物篮中是否有任何商品

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

这是我的帮助规范,我必须测试这个:

 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 

但是,当我运行测试时,我得到了

 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: 

从调试开始,我看到在@ request.session的ActionDispatch :: TestProcess中正在访问该会话 ,并且@request是nil。 当我从我的请求访问会话specs @request是ActionController :: TestRequest的一个实例。

我的问题是我可以从帮助程序规范访问会话对象吗? 如果我可以,怎么样? 如果我不能测试这种方法的最佳实践是什么?

**** 更新 * ***

这归结于在我的工厂中include ActionDispatch::TestProcess 。 删除此选项包括对问题进行排序。

我可以从帮助程序规范访问会话对象吗?

是。

 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: {} 

会话对象在那里并返回一个空哈希。

尝试更详细地查看回溯以查找错误。 stack level too deep通常表示递归出错。

你正在测试has_basket_items? ApplicationHelper中的操作,它使用篮子表中的basket_id检查特定篮子,因此您应该在测试中使用Factory_Girl gem创建一些篮子对象。

她是一个例子: –

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

您可以从此屏幕中获取有关如何使用factory_girl的更多详细信息http://railscasts.com/episodes/158-factories-not-fixtures

它将在测试数据库中创建Factory对象。 所以,基本上你可以创建一些工厂对象,然后在会话中设置一个basket_id来检查它的存在,如下所示:

 session[:basket_id] = basket1.id 

所以,你的测试应该是这样的: –

 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 

或者,您可以使用以下命令检查factory_girl创建的basket_id是否为be_true:

 session[:basket_id] = basket1.id helper.has_basket_items?.should be_true