Rails 6 和 Deliver_later 不影响 ActionMailer::Base.deliveries

问题描述 投票:0回答:4

升级到 Rails 6 后,我注意到默认邮件程序的

.deliver_later
的工作方式与 Rails 5 中不同。

配置:

config.active_job.queue_adapter = :inline

运行时

Mailer.register_email(...).deliver_later
-
ActionMailer::Base.deliveries
中不存储任何内容。如果我运行
perform_enqueued_jobs
,这个数组就会被填满 - 看起来
queue_adapter = :inline
无法按照我期望的方式工作。

如果我运行

Mailer.send(...).deliver_now
那么
ActionMailer::Base.deliveries
就有适当的价值。

知道为什么会发生这种情况以及如何解决这个问题吗?

delayed-job ruby-on-rails-6
4个回答
6
投票

我在测试中遇到了同样的问题。在互联网上搜索没有结果,所以我开始尝试。

我尝试将发送邮件的调用方法封装在

assert_emails 1 do
  Mailer.register_email(...).deliver_later
end

之后,

ActionMailer::Base.deliveries
已正确填充。


2
投票

问题

问题在于 Rails 6 中添加的两行新代码(第 1 行第 2 行), 基本上,在

here
(在 RSpec 中)和 here (在 Minitest 中)定义的回调 before_setup 被覆盖(by this),从而强制 queue_adapter 成为 test 适配器 而不是那个由
config.active_job.queue_adapter
定义。

解决方法

因此,为了使用

queue_adapter
定义的
config.active_job.queue_adapter
并恢复 Rails 5 行为,我们可以执行如下操作。

# spec/support/active_job/test_helper.rb
module ActiveJob
  module TestHelper
    def before_setup
      super
    end
  end
end

0
投票

如果电子邮件的确切数量可以轻松更改,这是另一种选择:

assert_changes 'enqueued_jobs.size' do
  # Some code that sends email with deliver_later
end

这允许您测试电子邮件是否已发送,但它忽略了确切的数量(这是

asserts_emails
方法的限制 - 除此之外,
asserts_emails
方法很棒)。 我发现
enqueued_jobs
方法对于测试任何后台作业非常有帮助,包括
deliver_later

注意:上面的示例仅检查排队的作业列表是否已更改。如果您想更具体并检查队列是否已通过电子邮件更改,您应该这样做:

assert_changes 'enqueued_jobs.select {|job| job["job_class"] == "ActionMailer::MailDeliveryJob"}.size' do
  # Some code that sends email with deliver_later
end


0
投票

assert_enqueued_emails
在这种情况下也可能有帮助

© www.soinside.com 2019 - 2024. All rights reserved.