- 嘿,伙计们,我需要帮助,我是新的测试和测试我的邮件,但我不明白你得到这个错误,当我运行我的测试。
- '预期
ActionMailer::Base.deliveries.size
已更改% 1,但已更改% 2' - 电子邮件由
after_create
钩子触发 - 我的代码按预期工作,但测试失败。任何有帮助的人都很感激。
验证邮件.rb
# frozen_string_literal: true
class VerifyMailer < ApplicationMailer
def verification_email(user)
@user = user
mail(to: user.email, subject: 'verification code')
end
end
verify_mailer_spec.rb
# frozen_string_literal: true
require 'rails_helper'
# include ActiveJob::TestHelper
RSpec.describe VerifyMailer, type: :mailer do
let(:user) { create(:user) }
let(:mail) { VerifyMailer.verification_email(user).deliver_now }
it 'renders the receiver email' do
expect(mail.to).to eq([user.email])
end
it 'renders the subject' do
expect(mail.subject).to eq('verification code')
end
it 'renders the sender email' do
expect(mail.from).to eq(['mutebigod10@gmail.com'])
end
end
user.rb
# frozen_string_literal: true
class User < ApplicationRecord
after_create :send_user_otp
attr_writer :login
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable ,
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, authentication_keys: [:username]
has_many :payments
validates :email, :username, presence: true, uniqueness: true
validates :username, format: { with: /\A[a-zA-Z0-9_.]*\z/,
message: ' only allow letter, number, underscore and punctuation marks' }
# Loggin with user_name
def login
@login || username
end
def send_user_otp
unverify!
otp = generate_codes
update_column(:otp_code, otp)
VerifyMailer.verification_email(self).deliver_now
touch(:otp_sent_at)
end
def unverify!
update_column(:verified, false)
end
def generate_codes
loop do
code = rand(0o00000..999_999).to_s
break code unless code.length != 6
end
end
end
- 我已经将config.action_mailer.delivery_method =:test添加到environment/test.rb
- 我还使用factory_bot_rails创建用户
FactoryBot.define do
factory :user do
sequence(:email) { |n| "person#{n}@example.com" }
sequence(:username) { |n| "user#{n}" }
password { '!Mutebi2' }
password_confirmation { '!Mutebi2' }
end
end
1条答案
按热度按时间to94eoyn1#
在大多数情况下,计算机完全按照您的要求执行操作:
使用
FactoryBot
创建user
会触发任何/所有回调:所以
create(:user)
在创建后调用:send_user_otp
。然后您发送另一封电子邮件
VerifyMailer.verification_email(user).deliver_now
因此,
ActionMailer::Base.deliveries.size
的变化为2。在
VerifyMailer
测试中,您正在测试电子邮件的属性,因此您不需要实际保存用户或实际发送电子邮件。如果您需要电子邮件的示例,只需删除
deliver_now
即可。您可以使用build
代替create
,使用user
:在
User
测试中,您可以验证创建用户也会创建电子邮件:请注意,我实际上根本没有测试
ActionMailer::Base.deliveries.size
。这是一个服务或请求测试,应该基于完整的实现,例如:填写本表时:
您的
User
模型不负责VerifyMailer
、ApplicationMailer
和任何其他处理delver_now
的代码,它只负责调用VerifyMailer
并将user
示例传递给它。VerifyMailer
不负责处理邮件的发送,它创建邮件并将其传递给ActionMailer
。让你的测试集中在你的代码的责任上,这将使它们不那么脆弱。
如果您在
ActionMailer
设置中进行了更改,您不希望User
测试开始失败。