URL helpers not working in test

I've been neglecting these errors for a weeks because I don't know
what's going on. My environment is rspec, capybara and factory_girl
under Rails 3.1.3 and Ruby 1.9.2. I'm also using spork and guard but
this happens without them.

The mailer tests are failing because apparently the UrlHelper isn't

1) User delivers email to user
     Failure/Error: user.send_password_reset
       No route matches
{:action=>"edit", :controller=>"password_resets"}
     # ./app/views/mailer/password_reset.text.erb:4:in
     # ./app/mailers/mailer.rb:11:in `password_reset'
     # ./app/models/user.rb:34:in `send_password_reset'
     # ./spec/models/user_spec.rb:12:in `block (2 levels) in <top

There is definitely a route for password_resets#edit
(resources :password_resets) and it works in development and
production, which is the confusing part. I think the tests aren't
configured correctly in my spec_helper.rb -- the gist for that is
here: https://gist.github.com/1449060

While an outright answer would be nice, I'd like to get help on how to
go about investigating this kind of thing better. Thanks in advance.

I think this one is a lesson in reading error messages closely. The
error message is No route matches
{:action=>"edit", :controller=>"password_resets"} and you protest
that you've got resources :password_resets in your routes file. But to
generate a url for a password reset edit, it needs to know which
password reset you're editing (i.e. id is a mandatory parameter in
that route). Since you've not passed an id parameter, rails can't
match your parameters against the passwords reset edit action.


Thanks, Frederick. You're always here to answer questions and I
appreciate that, as I'm sure are others. Your comment pointed me in
the right direction. It was a race condition between clearing out the
old token and creating the new one. So sometimes I'd get nil and other
times a valid value. The mailer template was passing in an id:
<%= edit_password_reset_url(@user.reset_token) %>

The user model had a function that reset the tokens, which it would
call before generating a new one. It was using a slightly different
method to set it than clear it and that caused a race condition. It
needed to commit the changes to the database after clearing the token,
and then generate a new one. It's an extra hit to the db but I don't
expect this to be called too often.

Thanks again.