使用rspec进行ActionMailer测试

Din*_*ngo 34 email rspec ruby-on-rails actionmailer

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

我已经使用该操作创建了所有电子邮件mailer,并且我使用rspecshoulda进行测试.我需要测试邮件是否正确收到了正确的用户.我不知道如何测试这种行为.

请告诉我如何测试ActionMailer使用shouldarspec.

CDu*_*Dub 55

有一个关于如何使用RSpec测试ActionMailer 的好教程.这是我遵循的做法,它还没有让我失望.

本教程适用于Rails 3和4.

如果上面链接中的教程中断,则以下是相关部分:

假设以下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
Run Code Online (Sandbox Code Playgroud)

以下测试配置:

# config/environments/test.rb
AppName::Application.configure do
  config.action_mailer.delivery_method = :test
end
Run Code Online (Sandbox Code Playgroud)

这些规格应该可以满足您的需求:

# 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
Run Code Online (Sandbox Code Playgroud)

关于此主题的原始博客文章向卢卡斯卡顿道具.

  • 但是如果你这样做就不会遇到任何问题,让我们说从User.send_instructions中捕获一个异常并向你发送一封例外的电子邮件.您只需测试是否发送*任何*电子邮件,而不是您的特定电子邮件. (3认同)
  • @Phillipp提出了一个很好的观点,如果你想测试特定的邮件,`ActionMailer :: Base.deliveries`是一个`Mail :: Message`对象的数组.请参阅[Mail :: Message API](http://www.rubydoc.info/github/mikel/mail/Mail/Message). (3认同)
  • 对于那些想知道为什么`mock_model`不起作用的人:http://stackoverflow.com/a/24060582/2899410 (2认同)