使用Rspec重置密码测试

时间:2015-12-28 06:43:21

标签: ruby-on-rails ruby rspec rspec-rails

我正在使用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

每次我运行它都会给你一个语法错误 "it { expect(ActionMailer::Base.deliveries.count(1) } "。 我想检查电子邮件是否成功发送,以及用户是否在电子邮件中有密钥。 谢谢!

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

你所遇到的问题最有可能通过编写更好的测试来解决。 这里通常是你如何为这样的事情编写测试。

让我们假设您的路线文件中有一个看起来像这样的邮政路线

# 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

然后您可以安装vcrfactory_girl宝石并像这样使用它们来测试您的邮件

# 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

最后,如果前端发生了某些事情,用户会点击发出此帖子请求,那么你也会为它编写功能测试。

希望这有帮助!