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

Ruby RSpec测试报错:如何模拟控制器实例变量的feature?方法?

解决RSpec测试中@domain为nil的问题

你遇到的undefined method 'feature?' for nil:NilClass错误,核心原因是测试时助手模块ApiHelpers所在的上下文没有初始化@domain实例变量。控制器里的@domain是在before钩子中赋值的,但测试助手模块时,这个钩子不会自动执行,所以需要手动给测试对象设置@domain。

步骤1:修正测试文件的基础错误

先把测试里的几个明显错误改过来:

  • 测试的模块名应该是ApiHelpers,不是ApiHelp
  • 测试的方法名要和助手方法一致:#find_lists,不是#find_matching_lists
  • 不需要模拟Domain.new,因为控制器里的@domain是从account.domain获取的,不是通过Domain.new创建的

步骤2:手动给测试对象设置@domain实例变量

在测试中,你需要给包含ApiHelpers模块的实例赋值@domain,并模拟它的feature?方法。

修正后的完整测试代码示例:

require "unit/spec_help"
require_project "api/helpers/play_help.rb"

RSpec.describe ApiHelpers do
  # 创建一个包含ApiHelpers模块的测试类,模拟控制器上下文
  class TestController
    include ApiHelpers
  end

  describe "#find_lists" do
    let(:domain_double) { double("Domain") }
    let(:test_instance) { TestController.new }
    let(:sample_params) { { some_key: "value" } }
    let(:folders) { double("Folders") }

    before do
      # 给测试实例设置@domain变量
      test_instance.instance_variable_set(:@domain, domain_double)
      # 模拟Domain的feature?方法返回true
      allow(domain_double).to receive(:feature?).with("BrandNewFeature").and_return(true)
      # 模拟ListQueries.folders返回预期结果
      allow(ListQueries).to receive(:folders).with(sample_params).and_return(folders)
    end

    it "returns folders when BrandNewFeature is enabled" do
      result = test_instance.find_lists(sample_params)
      expect(result).to eq(folders)
      expect(ListQueries).to have_received(:folders).with(sample_params)
    end

    it "returns nil when BrandNewFeature is disabled" do
      allow(domain_double).to receive(:feature?).with("BrandNewFeature").and_return(false)
      result = test_instance.find_lists(sample_params)
      expect(result).to be_nil
      expect(ListQueries).not_to have_received(:folders)
    end
  end
end

关键说明

  1. 测试类模拟上下文:创建TestController类并包含ApiHelpers,模拟助手模块在控制器中的运行环境。
  2. 设置实例变量:用instance_variable_set给测试实例手动赋值@domain,替代控制器before钩子的作用。
  3. 双对象模拟:用double创建domain_double,并模拟feature?方法的返回值,覆盖不同场景(功能开启/关闭)。

这样就能解决@domain为nil的问题,同时完整测试find_lists方法的逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 00:55:20