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

Rails 5.1.6调用ActiveJob::TestHelper触发SystemStackError错误求助

解决Rails集成测试中使用deliver_later+ActiveJob::TestHelper出现的stack level too deep错误

我之前也碰到过类似的问题,结合你的场景(Rails 5.1.6 + Ruby 2.5.1,从deliver_now切换到deliver_later后集成测试报错),这个栈溢出错误大概率是模块包含方式错误或者测试类继承与模块的冲突导致的,下面给你几个可行的解决方案:

1. 调整ActiveJob::TestHelper的包含位置

你现在是在测试文件顶部直接include ActiveJob::TestHelper,这种全局包含的方式很容易和ActionDispatch::IntegrationTest的内置逻辑冲突,引发无限递归。正确的做法是在测试类内部包含该模块:

require 'test_helper'

class SendJobToContactsTest < ActionDispatch::IntegrationTest
  # 把include放到类内部
  include ActiveJob::TestHelper

  def test_send_job_to_contacts
    # 示例测试逻辑:包裹需要触发job的代码
    perform_enqueued_jobs do
      # 这里写触发邮件发送的请求或方法调用,比如:
      post send_contacts_job_path
    end

    # 你的断言逻辑,比如检查邮件是否发送成功
    assert_equal 1, ActionMailer::Base.deliveries.size
  end
end

2. 根据测试场景选择合适的父类

如果你的测试核心是验证Job的执行逻辑,而非完整的端到端集成测试,可以考虑让测试类继承自ActiveJob::TestCase,而不是ActionDispatch::IntegrationTest,这样能避免集成测试模块和Job测试模块的冲突:

require 'test_helper'

# 切换父类为ActiveJob::TestCase
class SendJobToContactsTest < ActiveJob::TestCase
  def test_send_job_to_contacts
    # 验证Job是否被入队
    assert_enqueued_jobs 1 do
      # 触发邮件发送动作
      YourMailer.send_to_contacts.deliver_later
    end

    # 执行所有入队的Job并验证结果
    perform_enqueued_jobs
    assert_equal 1, ActionMailer::Base.deliveries.size
  end
end

3. 排查全局模块重复包含的问题

检查你的test_helper.rb文件,看看是否已经全局包含了ActiveJob::TestHelper(比如在ActiveSupport::TestCase里做了include)。如果是的话,你的测试类会重复包含该模块,导致方法重写引发递归。这种情况下,只需要去掉测试文件里的include ActiveJob::TestHelper即可。

4. 检查是否有自定义方法引发递归

如果你的测试代码或辅助方法里重写了ActiveJob::TestHelper中的方法(比如perform_enqueued_jobs、assert_enqueued_jobs),要确保重写的方法不会无限调用自身。比如如果你的自定义perform_enqueued_jobs里没有正确调用原方法或者终止条件,就会触发栈溢出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:24:23