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

Rspec stub两个包含同一模块的类时抛出Transaction::Overview未实现new方法错误

问题根源

该错误与RSpec是否支持stub引入同一模块的类无关,本质是Ruby常量查找歧义:
报错中提示没有new方法的是Transaction::Overview(这是个模块,本身确实无法实例化、没有new方法),说明RSpec执行第二个stub时,错误地将你指定的Actual::Overview/Adjustment::Overview解析成了Transaction::Overview模块。
这类问题多出现于Rails自动加载(懒加载)场景:第一次访问嵌套常量时解析正确,第二次查找同名嵌套常量时,Ruby错误命中了已经加载的Transaction::Overview模块。

解决方案

方案1:提前预解析常量(最推荐)

在测试用例的起始位置,或者对应describe块的最前端,先强制Ruby完成两个目标类的常量解析,避免后续查找出现歧义:

# 提前触发常量加载,固定解析结果
Actual::Overview
Adjustment::Overview

仅需两行代码即可触发Rails自动加载对应类,后续stub时常量查找就不会发生偏移。

方案2:显式获取常量

如果方案1不生效,可以通过const_get从顶层命名空间显式获取目标类,完全规避常量查找的歧义问题:

# 替换原有的stub逻辑
actual_overview_clz = Object.const_get("Actual::Overview")
expect(actual_overview_clz).to receive(:new).with(activity_presenter, report_presenter).at_least(:once).and_return(actual_overview)

adjustment_overview_clz = Object.const_get("Adjustment::Overview")
expect(adjustment_overview_clz).to receive(:new).with(activity_presenter, report_presenter).at_least(:once).and_return(adjustment_overview)

方案3:临时关闭部分双验证

如果你确认要stub的类确实存在new方法,也可以临时关闭RSpec的部分双校验绕开检查(不推荐,会跳过方法存在性校验,可能掩盖其他问题):

without_partial_double_verification do
  expect(Adjustment::Overview).to receive(:new).with(activity_presenter, report_presenter).at_least(:once).and_return(adjustment_overview)
end

额外排查点

可以检查测试文件、全局测试配置中是否有include Transaction之类的代码,这类写法会把Transaction下的常量引入当前命名空间,直接导致Overview的查找优先级变为Transaction::Overview优先,必然会触发解析错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 10:27:02