Ruby on Rails Testing - flash.now gotcha

Posted by Curtis Miller Curtis Miller

I finished the test for my models and it went pretty well. Today I started on the controller tests. Shortly after starting I ran into some curious Ruby on Rails behavior. I expected that the value of the flash variable would hold a certain value on an unsuccessful login attempt, but instead it was empty. I ran the server and tested it manually and there it was 'Invalid login or password.' appeared as an error flash on the page.

Turns out that flash.now is cleared after it is rendered in the view. That means you cannot get the value out in your tests. There is a workaround though. It is discussed on the Rails wiki and on Chu Yeow's Redemption in a Blog. So what is the workaround?

You must access the render viewed contents and look for the corresponding flash div. For example, my code looked like the following:

flash.now[:error] = 'Incorrect login or password.'

Which outputs a div into the view like this:

<div id='error'>Incorrect login or password.</div>

In your test you can use the assert_tag assertion to find the tag corresponding to the element you want. Following our example above, we want to find a div tag with an id of error and contents should contain 'Incorrect login or password'. This would look like:

assert_tag :tag => 'div',
           :attributes => { :id => 'error' },
           :content => 'Incorrect login or password.'

The wiki also talks about using @response.body but I have not looked in to that yet. I hope this helps.

Know of a better or alternate way? Share it in the comments.



Velocity Labs

Need web application development, maintenance for your existing app, or a third party code review?

Velocity Labs can help.

Hire us!