如何测试设置为稍后发送的电子邮件

How to test emails that are set to deliver later

我不知道如何使用语法来断言电子邮件已正确排队。具体来说,当参数是对象时,如何将参数传递给邮件程序?

例如,如果您想将联系人对象传递给文档中的示例:

  assert_enqueued_email_with ContactMailer, :welcome, @contact do
    ContactMailer.welcome(@contact).deliver_later
  end

  assert_enqueued_email_with ContactMailer, :welcome, args: @contact do
    ContactMailer.welcome.deliver_later
  end

  assert_enqueued_email_with ContactMailer, :welcome, [@contact] do
    ContactMailer.welcome.deliver_later
  end

None 其中似乎有效。如果您查看实际排队的作业,对象如下所示:

{:job=>ActionMailer::DeliveryJob, :args=>["ContactMailer", "welcome", "deliver_now", {"_aj_globalid"=>"gid://app_name/Contact/1015983224"}], :queue=>"mailers"}

感谢任何帮助!

您可以尝试指定等待时间

Notifier.welcome(User.first).deliver_later(wait: 1.hour)

deliver_later的更多选项:

http://api.rubyonrails.org/classes/ActionMailer/MessageDelivery.html#method-i-deliver_later

您需要传递一个参数数组:

assert_enqueued_email_with ContactMailer, :welcome, args: [@contact] do
  ContactMailer.welcome(@contact).deliver_later
end

我知道这可能为时已晚,无法为您提供帮助,但我最近 运行 遇到了同样的问题,因此希望此解决方法能帮助下一个人。在引擎盖下,assert_enqueued_email_with just uses assert_enqueued_with,我们可以直接使用它来创建一个测试,它将像这样找到排队的电子邮件。

assert_enqueued_with(job: ContactMailer.delivery_job, args: ['ContactMailer', 'welcome', 'deliver_now', @contact], queue: 'mailers')

此测试与 assert_enqueued_email_with 生成的唯一区别是 @contact 未包装在额外的数组中。

编辑:我想回来提一下,我只是在从 Rails 5.2 更新到 Rails 6.0 的过程中遇到了这个错误。一旦我深入更新,它就消失了,assert_enqueued_with 按预期工作,而以前使用 assert_enqueued_with 的解决方法不再匹配。具体来说是在将 delivery_job 设置为新的默认值之后。

Rails.application.config.action_mailer.delivery_job = "ActionMailer::MailDeliveryJob"

我遇到了同样的问题,所以我的解决方案是直接访问排队作业的数组并手动进行比较。

assert_equal ActiveJob::Base.queue_adapter.enqueued_jobs[0][:args][0], "UserMailer"
assert_equal ActiveJob::Base.queue_adapter.enqueued_jobs[1][:args][0], "MarketingMailer"