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

Rails7+Hotwire/Turbo Stream下Action Mailer计数系统测试问题

解决方案与排查步骤

1. 等待Turbo异步请求完成

Turbo Streams通过异步AJAX处理请求,Capybara默认不会自动等待Turbo操作完成,导致断言执行时邮件还未发送。

方法A:等待Turbo进度条消失

添加自定义方法等待Turbo加载完成:

def wait_for_turbo
  loop until page.has_no_css?('turbo-progress-bar', wait: 3)
end

修改测试代码,在点击后等待:

assert_difference('ActionMailer::Base.deliveries.count', 1) do
  click_link("approve_school_#{brittinglese.id}")
  wait_for_turbo
end

方法B:等待页面状态变化

如果点击按钮后页面有明确的UI反馈(如成功提示),直接等待该元素出现:

assert_difference('ActionMailer::Base.deliveries.count', 1) do
  click_link("approve_school_#{brittinglese.id}")
  expect(page).to have_content('学校已批准', wait: 5)
end

2. 验证Turbo请求的HTTP方法与路由匹配

确保按钮的data-turbo-method属性设置正确,比如触发批准动作需要patch或put方法:

<%= link_to '批准', approve_school_path(school), data: { turbo: true, turbo_method: :patch } %>

测试中可检查请求是否正确发送:

click_link("approve_school_#{brittinglese.id}")
wait_for_turbo
# 查看最后一次请求的方法和路径
last_request = page.driver.requests.last
puts "请求方法:#{last_request.method},路径:#{last_request.path}"

3. 确认异步邮件的执行时机

如果你的Action使用了deliver_later发送邮件,需确保测试环境中后台任务同步执行:

  • 若使用Sidekiq,在测试块中启用inline模式:
Sidekiq::Testing.inline! do
  assert_difference('ActionMailer::Base.deliveries.count', 1) do
    click_link("approve_school_#{brittinglese.id}")
    wait_for_turbo
  end
end
  • Rails默认测试环境下deliver_later会自动同步执行,若自定义了后台配置,需恢复默认行为。

4. 检查测试环境邮件配置

确保config/environments/test.rb中邮件配置为测试模式,邮件会存入deliveries数组:

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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 10:12:34