Rails 4 + Devise: How to write a test for Devise Reset Password without RSpec?

justindao picture justindao · Nov 10, 2014 · Viewed 7.6k times · Source

For reasons outside of my control, I can't use RSpec for testing in my current project. I'm trying to test Devise Reset Password, and I can't seem to come up with something that works.

Here's what I have so far:

require 'test_helper'

class ResetPasswordTest < ActionDispatch::IntegrationTest
  setup do
    @user = users(:example)
  end

  test "reset user's password" do 
    old_password = @user.encrypted_password

    puts @user.inspect

    # This assertion works
    assert_difference('ActionMailer::Base.deliveries.count', 1) do
      post user_password_path, user: {email: @user.email}
    end

    # puts @user.reset_password_token => nil
    # Not sure why this doesn't assign a reset password token to @user

    patch "/users/password", user: {
      reset_password_token: @user.reset_password_token, 
      password: "new-password", 
      password_confirmation: "new-password",
    }

    # I get a success here, but I'm not sure why, since reset password token is nil.
    assert_response :success

    # This assertion doesn't work. 
    assert_not_equal(@user.encrypted_password, old_password)
  end

end

I've added some comments above to where things don't seem to be working. Does anyone have an insight, or an idea about how better to test this?

Answer

sealocal picture sealocal · Apr 13, 2015

Devise tests the PasswordsController internally. I wanted to test my PasswordsController with extra functionality and went to Devise's controller tests for help in building tests for Devise's default functionality, then adding assertions for my new functionality into the test case.

As noted in other answers, you must obtain the reset_password_token. Instead of parsing a delivered email as in another solution here, you could obtain the token in the same way as Devise:

setup do
  request.env["devise.mapping"] = Devise.mappings[:user]
  @user = users(:user_that_is_defined_in_fixture)
  @reset_password_token  = @user.send_reset_password_instructions
end

Check out Devise's solution for the PasswordControllerTest:

https://github.com/plataformatec/devise/blob/master/test/controllers/passwords_controller_test.rb.