我正在使用rails,并希望在Rspec中编写一个密码重置测试。我对测试很陌生。这就是我迄今为止所做的:
require 'rails_helper'
describe UsersController, type: :controller do
describe 'post #reset_password' do
let(:user) { create(:user) }
context "reset password" do
def do_request
patch :update_password
end
before { do_request }
it { expect(ActionMailer::Base.deliveries.count(1) }
end
end
end
每次运行此程序时,都会在
中给ma一个语法错误CCD_ 1。我想检查电子邮件是否成功发送,以及用户是否在电子邮件中有密钥。谢谢
1)您最后在这里错过了)
,因此出现了语法错误
it { expect(ActionMailer::Base.deliveries.count(1) }
至
it { expect(ActionMailer::Base.deliveries.count(1)) }
2)如果您想检查总交付量。你可以试试
it 'should send an email' do
ActionMailer::Base.deliveries.count.should == 1
end
同时检查发送器
it 'renders the sender email' do
ActionMailer::Base.deliveries.first.from.should == ['notifications@domain.com']
end
同时检查主题行
it 'should set the subject to the correct subject' do
ActionMailer::Base.deliveries.first.subject.should == 'Here Is Your Story!'
end
您遇到的问题很可能会通过编写更好的测试来解决。以下是您编写类似测试的一般方法。
让我们假设在你的路线文件中,你有一个后路线,看起来像这个
# config/routes.rb
post "/user/:id/reset_password", to: "users#reset_password"
你的用户控制器看起来像这个
# app/controllers/users_controller.rb
class UsersController
...
def reset_password
user = User.find(params[:id])
user.reset_password!
SomeMailClass.email_reset_instructions(user)
end
end
你的User.rb模型看起来像这个
# app/models/user.rb
class User < ActiveRecord::Base
def reset_password!
update!(password: nil) # or whatever way you want/need to reset the password
end
end
你有某种类型的邮件类来发送你的电子邮件
# app/models/some_mail_class.rb
class SomeMailClass
def self.email_reset_instructions(user)
# do something to send email...
end
end
在控制器中进行测试的方法是
# spec/controllers/users_controller_spec.rb
require 'rails_helper'
describe UsersController, type: :controller do
it "#reset_password" do
user_id = double(:user_id)
user = double(:user)
expect(User).to receive(:find).with(user_id).and_return(user)
expect(user).to receive(:reset_password!).and_return(true)
expect(SomeMailClass).to receive(:email_reset_instructions).with(user)
post :reset_password, id: user_id
end
end
但你不应该就此打住。因为新制作的方法reset_password!
和SomeMailClass
的实现还有待测试。所以你应该为他们编写这样的模型/单元测试
# spec/models/user_spec.rb
require "rails_helper"
describe User do
it ".reset_password!" do
user = User.create(password: "foo")
expect(user.password).to eq "foo"
user.reset_password!
expect(user.password).to eq nil
end
end
然后您可以安装vcr
和factory_girl
gem,并像这样使用它们来测试您的邮件
# spec/models/some_mail_class_spec.rb
require "rails_helper"
describe SomeMailClass do
VCR.use_cassette "email_reset_instructions" do |cassette|
it ".email_reset_instructions" do
user = FactoryGirl.create(:user)
SomeMailClass.email_reset_instructions(user)
# you can write some expectations on the cassette obj to test.
# or you can write whatever expectations you need/desire
end
end
end
最后,如果前端发生了什么事情,用户会点击它发出这个帖子请求,你也会为它编写一个功能测试。
希望这能有所帮助!