Rails 5.1.6调用ActiveJob::TestHelper触发SystemStackError错误求助
我之前也碰到过类似的问题,结合你的场景(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

