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

Rails 7启用Turbo后Minitest的assert_difference失效问题

Turbo启用后Rails系统测试邮件断言失败的原因与修复方法

问题原因

Turbo 默认通过异步 AJAX 请求处理带有 data-turbo="true" 的链接,系统测试里的 click_link 方法执行后会立刻继续后续代码,不会等待 Turbo 完成后端请求和页面更新。而 assert_difference 块在 click_link 执行完毕后就会检查邮件计数,这时候后端还没来得及发送邮件,导致断言失败。

在未启用 Turbo 时,链接是同步请求,click_link 会等待页面完全加载后才继续,所以断言能正确捕获邮件发送的计数变化。

修复方案

方案1:等待页面状态更新(推荐)

在 click_link 后添加等待逻辑,确保后端请求完成后再结束断言块。比如等待页面出现审批完成的标识元素:

test 'welcome email gets sent on new user approval' do
  # ... 前置代码

  assert_difference('ActionMailer::Base.deliveries.count', 1) do
    click_link("super_admin_approves_user_#{user.id}")
    # 等待页面显示审批完成的状态文本或元素
    expect(page).to have_content('用户已审批')
  end

  # ... 后续断言
end

方案2:强制链接使用同步请求

修改视图中的链接,添加 data-turbo="false" 禁用 Turbo 异步处理,让请求回到传统的同步模式:

<%= link_to '审批用户', super_admin_approves_user_path(user), 
            id: "super_admin_approves_user_#{user.id}",
            data: { turbo: false } %>

这个方法无需修改测试代码,但会失去 Turbo 带来的无刷新体验,适合快速临时修复。

方案3:使用Turbo测试辅助方法等待导航

如果你的测试环境加载了 Turbo 的测试辅助工具,可以直接调用 turbo.wait_for_navigation 等待异步请求完成:

test 'welcome email gets sent on new user approval' do
  # ... 前置代码

  assert_difference('ActionMailer::Base.deliveries.count', 1) do
    click_link("super_admin_approves_user_#{user.id}")
    turbo.wait_for_navigation
  end

  # ... 后续断言
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:10:09