reevoolabs : open source technology

October 16, 2009

Problems with Cookie testing in Rails 2.3

Filed under: Uncategorized — craigsmith @ 4:38 pm

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!

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress