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
相关产品推荐
相关产品推荐

