Pre Rails 2.3, when you wanted to set the value of a cookie in a test you had to:
def test_should_set_user_name
#set cookie value
@request.cookies['visitor_name'] = CGI::Cookie.new('visitor_name', 'Dave')
post :login, :name => 'Dan'
assert_equal 'Dan', cookies['visitor_name'].value
end
But in 2.3 you can forget about all that CGI::Cookie crap and concentrate on the sweet code you actually want to test:
def test_should_set_user_name #set the cookie value@request.cookies['visitor_name']= 'Dave'post :login, :name => 'Dan' assert_equal 'Dan', cookies['visitor_name'].value end
Pretty!
The problem comes when you want to ensure that ‘Dave’ has been logged out. Consider this test:
def test_should_log_user_out
@request.cookies['visitor_name'] = 'Dave'
post :logout
assert_nil cookies['visitor_name']
end
This test always passes! No matter whether the cookie is removed in the logout action or not.
The solution
‘cookies’ is defined in ActionController::TestProcess as:
def cookies
@response.cookies
end
When you ask for cookies in your test, what you’re actually getting is @response.cookies which doesn’t include the values of the cookies set in the request. This means that cookies['visitor_name'], as far as the test is concerned, is never set, making it pass incorrectly.
I’ve written a simple patch which has recently been merged in to Rails. It merges the @response cookie with the @request cookie and returns that, rather than just returning the @response.cookie. So ActionController::TestProcess becomes:
def cookies @request.cookies.merge(@response.cookies) end
If you’re interested you can find the patch here.
Happy testing!

