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:
@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):
@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:
# 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.
# 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.