Rails Cookie Testing Notes

I ran into a few gotchas I wanted to document about testing and cookies in Rails while developing a user persistence system for a site. The implementation isn't really important, but the nuances of cookie accessing is what I really wanted to focus on.

In a functional test (and possibly an integration test, but I don't really touch those), you can set pre-populated cookie variables like so:

def test_cookie
  @request.cookies[:persist] = 'secret'
  get :index
  assert_response :success
end

The above code will set a cookie named "persist" to the value "secret." The subsequent request (get :index in this case) will have that cookie available to it during the action's lifecycle.

One thing to note, however, is that the cookies hash in a functional test is populated after a request has been made, and is only populated with cookies that were set during the request. What does this mean for us? It means this code will not work (assuming the index page does not set any cookies for us):

def test_cookie
  @request.cookies[:persist] = 'secret'
  get :index
  assert_equal 'secret', cookies['persist'] # This will fail as the cookies hash is empty
end

The reason the cookies hash is empty is because no cookies were set during the call to the index action. Think of the cookies hash as you would the assigns hash: It's only filled if you fill it during the request.

Another issue I ran into was testing for the deletion of a cookie. It's a simple fix, but it's something none-the-less:

def test_cookie
  # This action deletes the "persist" cookie via cookies.delete(:persist)
  delete :destroy
  assert_nil cookies['persist'] # This will fail as the value is actually empty, not nil
  assert cookies['persist'].empty? # This will succeed
end

Finally, unlike the assigns hash, you cannot access the cookies hash after a request using a symbol. You must identify the cookie's key by string, even if you set the cookie's key in your action as a symbol. There's a patch for this (Ticket #5924) but nothing is really being done about it.

def test_cookie
  # This action sets the "persist" cookie to '1'
  post :create
  assert_equal '1', cookies[:persist] # This will fail
  assert_equal '1', cookies['persist'] # This will succeed
end

So there you go. A few issues you might run into when testing with cookies.

Leave a Reply