Read more

RSpec: How to write isolated specs with cookies

Felix Eschey
August 30, 2023Software engineer at makandra GmbH


Rails offers several methods to manage Show snapshot three types of different cookies along with a session storage for cookies Show snapshot . These are normal, signed and encrypted Show snapshot cookies.

Illustration online protection

Rails Long Term Support

Rails LTS provides security patches for old versions of Ruby on Rails (2.3, 3.2, 4.2 and 5.2)

  • Prevents you from data breaches and liability risks
  • Upgrade at your own pace
  • Works with modern Rubies
Read more Show snapshot

By following the happy path of testing a web application, that is only the main use-case is tested as a integration test and the rest as isolated (more unit like) tests, one might want to test some cookie dependent behavior as a request, helper or model spec too.

Since the rspec documentation Show snapshot on testing cookies is rather sparse and only focuses on controller specs, which are not recommended to use since rails 5+ ( see "Rails: Support for Rails 5" Show snapshot ), this card will summarize some guidance on how to spec with cookies.


Note that using request.cookies and response.cookies is not recommend Show snapshot by rspec anymore as can be read in the documentation link Show snapshot above.

Model specs

Whenever you have to use the same cookie dependent logic between controllers and some controller helpers, you should extract that into a class to DRY up your code and write solid unit tests.

Beware that your class will not be able to read the cookies, since they are only available within the controller and view context. Because of that, consider passing the required cookie value to the model initialization:

class Movie::FavoriteMovieCookies

  attr_reader :favorite_movie_ids

  def initialize(cookies, movie_id)
    @favorite_movies_cookie_value = cookies.signed[:favorite_movies]
    @movie_id = movie_id

    set_favorite_movie_ids # read out from the cookie values
   ... # some methods to parse and manipulate the cookies value

If it is not an option to stub the cookies jar object, you can create one by using:

cookies_jar =, {})
cookies_jar.signed[:test] = 'test'

However #signed or #encrypted won't work within the model context on cookies_jar and will require stubbing these method or having to assure some of the cookies dependencies.

Helper Specs

Setting cookies in a helper spec Show snapshot shows that the cookies can simply set or expect by using one of the following options:

helper.cookies[:foo] = "bar"
helper.cookies.signed[:foo] = "bar"
helper.cookies.encrypted[:foo] = "bar"

Request Specs

In request specs you can simply access the current cookies by calling cookies. If you want to add a cookie before a request Show snapshot you can simply set the cookie on the cookies object as usual.

Signed and encrypted cookies

Even though the cookies method is available within the request spec, it is not working for signed and encrypted cookies.


One can simply decrypt the cookies by creating Show snapshot an object of ActionDispatch::Cookies::CookieJar. The reason for this is, that request specs use a Rack::Test::CookieJar object, while only ActionDispatch::Cookies::CookieJar supports the #encrypt and #signed methods.

If you do have to set an encrypted or signed cookie before the request you can use a ActionDispatch::Cookies::CookieJar object for this as well:

cookies_jar =, cookies.to_hash)
cookies_jar.signed[:user_id] = 1
cookes[:user_id] = cookies_jar[:user_id]

get "/movies/#{user_id}/favorite"


describe '/movies/:id/favorite' do
  def cookies_jar, cookies.to_hash)

  it 'sets the cookies' do
    movie = create(:movie)
    user = sign_in(role: 'admin')
    patch "/movies/#{}/favorite"
    expect(cookies_jar.signed[:favorite_movies]).to eq "{\"#{}\":[\"#{}\"]}"
Felix Eschey
August 30, 2023Software engineer at makandra GmbH
Posted by Felix Eschey to makandra dev (2023-08-30 15:05)