【问题标题】:ActionMailer testing with rspec [closed]使用 rspec 进行 ActionMailer 测试 [关闭]
【发布时间】:2013-11-27 19:00:35
【问题描述】:

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

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

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

【问题讨论】:

    标签: ruby-on-rails email rspec actionmailer


    【解决方案1】:

    如何使用 RSpec 测试 ActionMailer

    假设以下Notifier mailer 和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 推荐关于此主题的原始博客文章。

    【讨论】:

    • 但是,如果您从 User.send_instructions 中捕获异常并给自己发送一封包含该异常的电子邮件,那不会有任何问题。您只需测试是否发送了 任何 电子邮件,而不是您的特定电子邮件。
    • @Phillipp 提出了一个很好的观点,如果您想测试特定的邮件,ActionMailer::Base.deliveriesMail::Message 对象的数组。参考Mail::Message API
    • 对于那些想知道为什么mock_model 不起作用的人:stackoverflow.com/a/24060582/2899410
    • 想测试deliver_later的小伙伴也可以看看这个帖子:stackoverflow.com/a/42987726/11792577
    猜你喜欢
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 2016-06-30
    • 2017-07-22
    • 2019-03-08
    • 1970-01-01
    相关资源
    最近更新 更多