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

请求头处理模块的RSpec测试失败,求正确测试代码方案

解决ApiHelper模块的RSpec测试失败问题

问题背景

编写了用于处理第三方API请求头的ApiHelper模块,对应的RSpec测试始终失败,无法验证请求头的设置逻辑。

原模块代码

module ApiHelper
  def self.get_header(header)
    @request['Accept'] = header[:accept].blank? ? 'application/json' : header[:accept]
    @request['Content-Type'] = header[:content_type].blank? ? 'application/json' : header[:content_type]
  end
end

原测试代码

describe '.get_header' do
  let(:request) { double('request') }

  before do
    allow(ApiHelper).to receive(:get_header).and_call_original
    allow(ApiHelper).to receive(:instance_variable_get).and_return(request)
    allow(request).to receive(:[]=)
  end

  context 'when header values are provided' do
    let(:header) { { accept: 'application/json', content_type: 'application/json' } }

    it 'sets the Accept and Content-Type header values' do
      ApiHelper.get_header(header)
      expect(request).to have_received(:[]=).with('Accept', 'application/json')
      # expect(request).to have_received(:[]=).with('Content-Type', 'application/json')
    end
  end

  context 'when header values are not provided' do
    let(:header) { {} }

    it 'sets default values for the Accept and Content-Type headers' do
      ApiHelper.get_header(header)
      expect(request).to have_received(:[]=).with('Accept', 'application/json')
      expect(request).to have_received(:[]=).with('Content-Type', 'application/json')
    end
  end
end

测试失败信息

Failures:

  1) ApiHelper.get_header when header values are provided sets the Accept and Content-Type header values
     Failure/Error: expect(request).to have_received(:[]=).with('Accept', 'application/json')
     
       (Double "request").[]=("Accept", "application/json")
           expected: 1 time with arguments: ("Accept", "application/json")
           received: 0 times
     # ./spec/helpers/api_helper_spec.rb:41:in `block (4 levels) in <top (required)>'

  2) ApiHelper.get_header when header values are not provided sets default values for the Accept and Content-Type headers
     Failure/Error: expect(request).to have_received(:[]=).with('Accept', 'application/json')
     
       (Double "request").[]=("Accept", "application/json")
           expected: 1 time with arguments: ("Accept", "application/json")
           received: 0 times
     # ./spec/helpers/api_helper_spec.rb:51:in `block (4 levels) in <top (required)>'

Finished in 0.23741 seconds (files took 1.39 seconds to load)
4 examples, 2 failures

失败原因分析

原测试试图通过 stub instance_variable_get 方法来返回mock的request对象,但实际模块的get_header方法是直接访问@request类实例变量,并没有调用instance_variable_get方法。这个stub完全没生效,导致代码中的@request为nil,自然不会触发[]=方法调用,测试断言失败。

修复后的测试代码

describe '.get_header' do
  let(:request) { double('request') }

  before do
    allow(ApiHelper).to receive(:get_header).and_call_original
    # 直接给ApiHelper设置@request实例变量,替代无效的stub
    ApiHelper.instance_variable_set(:@request, request)
    allow(request).to receive(:[]=)
  end

  context 'when header values are provided' do
    let(:header) { { accept: 'application/json', content_type: 'application/json' } }

    it 'sets the Accept and Content-Type header values' do
      ApiHelper.get_header(header)
      expect(request).to have_received(:[]=).with('Accept', 'application/json')
      expect(request).to have_received(:[]=).with('Content-Type', 'application/json')
    end
  end

  context 'when header values are not provided' do
    let(:header) { {} }

    it 'sets default values for the Accept and Content-Type headers' do
      ApiHelper.get_header(header)
      expect(request).to have_received(:[]=).with('Accept', 'application/json')
      expect(request).to have_received(:[]=).with('Content-Type', 'application/json')
    end
  end
end

修复说明

  • 用ApiHelper.instance_variable_set(:@request, request)直接给模块设置类实例变量,确保get_header方法能访问到mock的request对象
  • 移除了无效的allow(ApiHelper).to receive(:instance_variable_get).and_return(request)代码
  • 恢复了第二个断言(注释掉的Content-Type验证),确保完整覆盖逻辑

修复后运行测试,两个场景都会通过,验证请求头的设置逻辑符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:45:38