使用rspec进行ActionMailer测试

42

我正在开发一个涉及发送/接收邮件的Rails 4应用程序。例如,在用户注册、用户评论以及应用程序中的其他事件期间,我会发送电子邮件。

我使用mailer操作创建了所有的电子邮件,并且我使用了rspecshoulda进行测试。我需要测试邮件是否被正确地发送给了相应的用户。我不知道如何测试这种行为。

请向我展示如何使用shouldarspec测试ActionMailer

1个回答

67

如何使用 RSpec 测试 ActionMailer

假设以下Notifier邮件发送器和User模型:

class Notifier < ActionMailer::Base
  default from: 'noreply@company.com'

  def instructions(user)
    @name = user.name
    @confirmation_url = confirmation_url(user)
    mail to: user.email, subject: 'Instructions'
  end
end

class User
  def send_instructions
    Notifier.instructions(self).deliver
  end
end

并且以下是测试配置:

# config/environments/test.rb
AppName::Application.configure do
  config.action_mailer.delivery_method = :test
end

这些规格应该能够满足您的需求:

# spec/models/user_spec.rb
require 'spec_helper'

describe User do
  let(:user) { User.make }

  it "sends an email" do
    expect { user.send_instructions }.to change { ActionMailer::Base.deliveries.count }.by(1)
  end
end

# spec/mailers/notifier_spec.rb
require 'spec_helper'

describe Notifier do
  describe 'instructions' do
    let(:user) { mock_model User, name: 'Lucas', email: 'lucas@email.com' }
    let(:mail) { Notifier.instructions(user) }

    it 'renders the subject' do
      expect(mail.subject).to eql('Instructions')
    end

    it 'renders the receiver email' do
      expect(mail.to).to eql([user.email])
    end

    it 'renders the sender email' do
      expect(mail.from).to eql(['noreply@company.com'])
    end

    it 'assigns @name' do
      expect(mail.body.encoded).to match(user.name)
    end

    it 'assigns @confirmation_url' do
      expect(mail.body.encoded).to match("http://aplication_url/#{user.id}/confirmation")
    end
  end
end

感谢Lucas Caton在这个主题上的原始博客文章。


3
但是如果您捕获了来自“User.send_instructions”方法的异常并向自己发送了一封电子邮件,那么这种测试就无法捕捉到任何问题。您只是测试是否发送了任何电子邮件,而不是您特定发送的电子邮件。 - Phillipp
4
@Phillipp提出了一个好观点,如果您想测试特定的邮件,可以使用ActionMailer::Base.deliveries,它是一个Mail::Message对象的数组。请参考Mail::Message API - janechii
2
对于那些想知道为什么mock_model不起作用的人:https://dev59.com/Q2Ag5IYBdhLWcg3wBXAR#24060582 - Aesthetic
对于那些想要测试deliver_later的人,请查看此帖子:https://dev59.com/vl4c5IYBdhLWcg3wsb_I#42987726 - glinda93

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接