Panasonic Youth rob sanheim writes about software, business, ruby, music, stuff and things



Posted
22 July 2006 @ 2am

Tagged
Rails, Ruby, TDD

Discuss

Testing named routes or url_for in functional test

If you've ever tried using named routes or url_for in functional tests, you might have seen an error like this:

1) Error:
test_article_override_to_meta(ArticleControllerTest):
NoMethodError: You have a nil object when you didn't expect it!
The error occured while evaluating nil.rewrite
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/base.rb:461:in `url_for'
generated/routing/named_routes/article.rb:2:in `article_url'
/usr/local/lib/ruby/gems/1.8/gems/actionpack-1.12.1/lib/action_controller/test_process.rb:431:in `method_missing'
test/functional/article_controller_test.rb:32:in `test_article_override_to_meta'

What is happenening here is that ActionController uses the current request as its context for creating new urls, so for instance if you do url_for :action => "create" it will use the current controller from the current request. So, if you write a functional test that tries kick things off with url_for (or a named route, which really just calls url_for under the covers) it fails as there is no current url.

Tracing into ActionController, @url gets created by a private method which is in the whole request cycle - so mocking it out probably isn't worth the trouble.

The solution is simple - call a simple, easy url (preferably without side effects - like index) before you use the named route or url_for. For example:

def test_article_url
    get :index
    url = article_url :controller => "article", :id => 1234
    assert_equal "http://host/article/1234", url
end

If you wanted to keep this drier you could move the get :index into your setup or into a helper method if it only applies to some of your test cases.


No Comments Yet


There are no comments yet. You could be the first!

Leave a Comment

Gmail Finally Adds Mass Delete Ruby Cookbook released - 900 pages?!