我正在为我的Rails 5 API编写测试,以确认每当用户请求重置密码时都会生成password_reset_token。
我有一个简短的password_reset_controller来处理初始请求:
class PasswordResetController < ApplicationController
def new
@user = User.find_by(email: params[:email].to_s.downcase)
@user.send_password_reset if @user
end
end
send_password_reset是我的用户模型中的一个方法,它调用generate_password_reset_instructions:
def send_password_reset
self.generate_password_reset_instructions
UserMailer.password_reset(self).deliver
end
def generate_password_reset_instructions
self.password_reset_token = SecureRandom.hex(10)
self.password_reset_sent_at = Time.now.utc
save
end
这应该将password_reset_token保存到我的db(事实上,当我调试它时,我知道它通过这些代码行)。以下测试套件通过,但最后一个测试套件除外:
require 'rails_helper'
RSpec.describe 'Password Reset API' do
let!(:user) { create(:user) }
describe 'POST password_reset/new' do
it 'returns status code 204 with user found' do
post '/password_reset/new', params: {email: user.email}
expect(response).to have_http_status(204)
end
it 'returns status code 204 with no user found' do
post '/password_reset/new', params: {email: 'not#anemail.com'}
expect(response).to have_http_status(204)
end
it "sends an email" do
expect { UserMailer.password_reset(user).deliver }.to change { ActionMailer::Base.deliveries.count }.by(1)
end
it 'confirmation_email is sent to the right user' do
UserMailer.password_reset(user).deliver
mail = ActionMailer::Base.deliveries.last
expect(mail.to[0]).to eq user.email
end
it 'generates password_reset_token' do
expect { post '/password_reset/new', params: {email: user.email} }.to change { user.password_reset_token }
end
end
end
我在终端获得的结果是:
Failures:
1) Password Reset API POST password_reset/new generates password_reset_token
Failure/Error: expect { post '/password_reset/new', params: {email: user.email} }.to change { user.password_reset_token }
expected result to have changed, but is still nil
# ./spec/requests/password_reset_spec.rb:28:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:56:in `block (3 levels) in <top (required)>'
# ./spec/rails_helper.rb:55:in `block (2 levels) in <top (required)>'
这似乎可能是由于没有保存到测试数据库的值,但是在其他帖子中提出建议(如移动ENV['RAILS_ENV'] ||= 'test'
)到rails_helper.rb的顶部并不能解决问题。我知道实际的方法是有效的,因为我能够通过运行服务器和发出请求来手动获得所需的结果,我只是不能编写测试来确认它确实有效。正如我的测试中的语法所表明的那样,我在测试中使用FactoryGirl来生成用户。
关于为什么最后一次测试(it 'generates password_reset_token' do
)未通过的任何想法?
答案 0 :(得分:3)
RSpec.describe 'Password Reset API' do
let!(:user) { create(:user) }
....
it 'generates password_reset_token' do
expect { post '/password_reset/new', params: {email: user.email} }.to change { user.password_reset_token }
end
end
您的期望:
发生了什么:
您需要做的是reload
使用user.reload.password_reset_token
fruits = ['apple', 'orange', 'blueberry', strawberry']
您的测试对象