8

I am trying to mock out the session hash for a controller like so:

it "finds using the session[:company_id]" do
  session.should_receive(:[]).with(:company_id).and_return 100
  Company.should_receive(:find).with(100)
  get 'show'
end

When I call get 'show' it states:

received :[] with unexpected arguments  
expected: (:company_id)  
   got: ("flash")

The controller code looks like:

def show
  company_id = session[:company_id]
  @company = Company.find params[company_id]
end

I have also simply tried setting

it "finds using the session[:company_id]" do
  session[:company_id]= 100
  Company.should_receive(:find).with(100)
  get 'show'
end

but then get an issue about:

expected: (100)
got: (nil)

Anyone have ideas why?

iltempo
  • 15,718
  • 8
  • 61
  • 72
Adam T
  • 251
  • 3
  • 13
  • Here is my answer for this question: http://stackoverflow.com/questions/8043956/rspec-2-7-access-controller-session-in-spec-before-making-request/13369734#13369734 – Dan K.K. Nov 13 '12 at 22:12

4 Answers4

5

I just ran into this. I couldn't manage to get should_receive to not interfere with the flash stuff.

But this let me test the behavior I was looking for:

it "should redirect to intended_url if set" do
  request.env['warden'] = double(:authenticate! => true)
  session.stub(:[]).with("flash").and_return double(:sweep => true, :update => true, :[]= => [])
  session.stub(:[]).with(:intended_url).and_return("/users")
  post 'create'
  response.should redirect_to("/users")
end

Hope that helps...

stuartc
  • 2,244
  • 2
  • 24
  • 31
3

I could not figure out how to mock the session container itself, however in most cases simply passing session data with request should be enough. So the test would split into two cases:

it "returns 404 if company_id is not in session" do
  get :show, {}, {}
  response.status.should == 404 # or assert_raises depending on how you handle 404s
end

it "finds using the session[:company_id]" do
  Company.should_receive(:find).with(100)
  get :show, {}, {:company_id => 100}
end

PS: forgot to mention I'm using some customized helpers from this snippet.

Community
  • 1
  • 1
Tadas Sasnauskas
  • 2,183
  • 1
  • 22
  • 24
0

try this:

session.expects(:[]).with(has_entries('company_id' => 100))
simo
  • 23,342
  • 38
  • 121
  • 218
-1

It's because you fetch flash session from your controller. So define it. Flash is save in session.

it "finds using the session[:company_id]" do
  session.stub!(:[]).with(:flash)
  session.should_receive(:[]).with(:company_id).and_return 100
  Company.should_receive(:find).with(100)
  get 'show'
end
shingara
  • 46,608
  • 11
  • 99
  • 105
  • I tried this but I still get an error 1) CompanyController GET 'show' finds using the session[:company_id] Failure/Error: get 'show' undefined method `sweep' for nil:NilClass # /Users/adam/.rvm/gems/ruby-1.8.7-p299/gems/activesupport-3.0.0/lib/active_support/whiny_nil.rb:48:in `method_missing'... – Adam T Sep 12 '10 at 22:42
  • `session` variable is not available until the request (get) is made. This won't work. – user181677 Jun 01 '21 at 01:06