I got stuck for a few minutes trying to figure out how to write a unit test to check if a value was being set in the flash using flash.now. In Rails’ Test::Unit you can’t just do something like assert_not_nil flash[:notice] because the flash value is discarded at the end of the request, and so the flash is always nil.
The solution is to use Mocha to mock an instance of ActionController::Flash::FlashHash and capture the value being set. Here was my solution:
def test_create_with_empty_email_sets_error_in_flash
hash = {}
ActionController::Flash::FlashHash.any_instance.expects(:now).returns(
hash
)
post :create
assert_not_nil hash[:error]
end
Funny thing, I remember having problems testing flashes with rspec also (I think my problem was with flash.now[:something], not with flash[:...], but, anyway….)
In the end I ended doing something like:
class SomeController < ApplicationController
def some_action
…
flash_now(:notice, “hello”)
end
private
def flash_now(key, something)
flash.now[key] = something
end
end
Then I could spec the action with something like
it “should blah blah”
…
controller.should_receive(:flash_now).with(:notice, “Hello”)
end
May not be the best example (you can argue now the problem is testing flash_now method
) but what I try to say is that sometimes is easier to change a little the code to make it more “testable”.
Since Rails 2.1 you can simply do:
def test_create_with_empty_email_sets_error_in_flash
post :create
assert_not_nil flash[:error]
end
(from Carlos Brando’s free book: Ruby On Rails 2.1 - What’s new)