Read more

Controller specs do not persist the Rails session across requests of the same spec

Arne Hartherz
April 10, 2013Software engineer at makandra GmbH

In specs, the session never persists but is always a new object for each request. Data put into the session in a previous request is lost. Here is how to circumvent that.

What's going on?

Illustration UI/UX Design

UI/UX Design by makandra brand

We make sure that your target audience has the best possible experience with your digital product. You get:

  • Design tailored to your audience
  • Proven processes customized to your needs
  • An expert team of experienced designers
Read more Show archive.org snapshot

You are making ActionController::TestRequests in your specs, and their #initialize method Show archive.org snapshot does this:

self.session = TestSession.new

This means that each time you say something like "get :index", the session in your controller will just be a new one, and you won't see anything you put into your session in a previous request.

Working around the issue

You can avoid that behavior by stubbing the controller's session and querying that stub:

persisted_session = ActionController::TestSession.new
controller.stub :session => persisted_session
# do things
persisted_session[:something].should ...

Apply this workaround only when you need it. Stubbing controller.session is not entirely the same, but good enough in most cases.

Example

If you, for example, had code that increments a "page_views" entry for every request you make, you could then test it like this:

get :index
persisted_session[:page_views].should == 1 # session[:page_views] is 1, so that would still work

get :index
persisted_session[:page_views].should == 2 # session[:page_views] would be 1, even though it works in the real world
Posted by Arne Hartherz to makandra dev (2013-04-10 15:08)