You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至Rails 6后ActionMailer测试失败问题求助

解决Rails 6升级后ActionMailer测试失败的问题

嘿,我来帮你搞定这个Rails升级后的邮件测试问题!你遇到的情况其实是Rails 6对邮件投递机制做了默认变更,再加上你配置的:classic自动加载器,才导致测试里的邮件没被正确统计到ActionMailer::Base.deliveries数组中。下面是具体的解决步骤:

1. 在测试中强制执行异步邮件任务

Rails 6默认使用ActionMailer::MailDeliveryJob(替代旧版的ActionMailer::DeliveryJob)来异步投递邮件,而测试环境默认不会自动执行队列中的任务,所以邮件不会立刻出现在deliveries里。你可以用perform_enqueued_jobs包裹触发邮件的操作,强制任务执行:

test "send email" do
  VCR.use_cassette('mailgun api key') do
    ActionMailer::Base.deliveries.clear
    item = items(:saved)
    
    # 包裹触发邮件的操作,强制执行队列中的投递任务
    perform_enqueued_jobs do
      visit item_path(item)
      click_button "Send"
    end
    
    assert_equal 1, ActionMailer::Base.deliveries.count
  end
end

如果想让所有测试都自动执行队列任务,也可以在test/test_helper.rb的测试基类里全局配置:

class ActiveSupport::TestCase
  # ... 保留原有配置
  setup do
    # 确保邮件投递功能处于开启状态
    ActionMailer::Base.perform_deliveries = true
    # 自动执行所有入队的异步任务
    perform_enqueued_jobs
  end
end

2. 确保:classic自动加载器能正确加载邮件Job

因为你设置了config.autoloader = :classic,需要确认ActionMailer::MailDeliveryJob能被正确加载。默认情况下app/mailers目录已经在自动加载路径中,但可以手动在config/application.rb里明确声明,避免加载问题:

config.autoloader = :classic
# 确保邮件相关目录被包含在自动加载路径内
config.autoload_paths << Rails.root.join('app/mailers')

3. 核对测试环境的邮件配置

最后检查一下config/environments/test.rb里的邮件配置,确保是测试模式(默认应该是正确的,但升级后可以再确认):

config.action_mailer.delivery_method = :test
config.action_mailer.perform_deliveries = true

问题根源说明

Rails 6把邮件投递的默认行为从同步的deliver_now改成了异步的deliver_later,对应的Job类也换成了ActionMailer::MailDeliveryJob。在测试环境中,异步任务不会自动执行,所以邮件不会被投递到deliveries数组,导致你看到的Expected: 1 Actual: 0断言失败。另外:classic自动加载器如果没有正确包含邮件目录,可能会导致Job无法被加载,进一步触发这个问题。

内容的提问来源于stack exchange,提问作者RomanOks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:34:56