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

如何用Rails和RSpec正确测试类方法?HTTParty调用报错排查

问题:RSpec测试中HTTParty的post方法未被识别

环境:Rails 6.1、Ruby 2.6.3、RSpec 3.12

已安装的测试Gem依赖:

group :test do
  gem 'cucumber-rails', :require => false
  gem 'database_cleaner'
  gem 'rspec-rails'
  gem "capybara", ">= 2.15"
  gem "selenium-webdriver"
  gem "webdrivers"
  gem "httparty", "~> 0.18.1"
end

测试文件spec/services/santander_payslip_controller.rb代码:

require 'rails_helper'
require 'payslip'

describe Payslip, type: :service do

    describe ".authenticate" do
      santander = Payslip::Santander.new "xxxx", "xxxx", "xxxx"
      context "given the client_id and client_secret" do
      
        it "fails without the digital certificate" do
          expect(santander.authenticate()).not_to eql('201')
        end
      
      end
    
    end

end

被测试的Payslip::Santander类代码:

module Payslip  

  class Santander
    include HTTParty
    
    def initialize(client_id, client_secret, account_id)
      @client_id = client_id
      @client_secret = client_secret
      @account_id = account_id
      @base_uri = Rails.configuration.santander_base_uri
    end

    def authenticate()
      url = @base_uri + '/token'
      params = {
        "client_id" => @client_id,
        "client_secret" => @client_secret,
        "grant_type" => "client_credentials"
      }
      payload = {body: params}
      response = post(url, payload).symbolize_key
      response.code
    end

end

运行rspec命令后报错:

F

Failures:

  1) Payslip.authenticate given the client_id and client_secret fails without the digital certificate
     Failure/Error: response = post(url, payload).symbolize_key

     NoMethodError:
       undefined method `post' for #<Payslip::Santander:0x0000000108e51330>
      ./app/services/payslip.rb:23:in `authenticate'
      ./spec/services/santander_payslip_controller_spec.rb:11:in `block (4 levels) in <top (required)>'

Finished in 0.01818 seconds (files took 3.95 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/services/santander_payslip_controller_spec.rb:10 # Payslip.authenticate given the client_id and client_secret fails without the digital certificate

错误原因

  1. HTTParty的post是类方法,当你在类中include HTTParty时,实例无法直接调用该方法,必须通过类本身调用。
  2. 代码中存在两个语法错误:symbolize_key应为复数形式symbolize_keys;类定义缺少闭合的end。

解决方案

1. 修复HTTParty调用方式

在authenticate方法中,将post改为self.class.post,通过类实例调用类级别的请求方法:

def authenticate()
  url = @base_uri + '/token'
  params = {
    "client_id" => @client_id,
    "client_secret" => @client_secret,
    "grant_type" => "client_credentials"
  }
  payload = {body: params}
  response = self.class.post(url, payload).symbolize_keys # 修正post调用和方法名
  response.code
end

2. 补全类的闭合end

在Payslip::Santander类和模块末尾添加缺失的end:

module Payslip  

  class Santander
    include HTTParty
    
    def initialize(client_id, client_secret, account_id)
      @client_id = client_id
      @client_secret = client_secret
      @account_id = account_id
      @base_uri = Rails.configuration.santander_base_uri
    end

    def authenticate()
      url = @base_uri + '/token'
      params = {
        "client_id" => @client_id,
        "client_secret" => @client_secret,
        "grant_type" => "client_credentials"
      }
      payload = {body: params}
      response = self.class.post(url, payload).symbolize_keys
      response.code
    end
  end # 补全类的闭合end
end # 补全模块的闭合end

3. 优化测试代码(可选)

调整测试结构,让实例化逻辑更规范,同时明确描述实例方法:

require 'rails_helper'
require 'payslip'

describe Payslip::Santander, type: :service do # 直接描述具体类更清晰

  describe "#authenticate" do # 实例方法用#标识,类方法用.
    let(:santander) { Payslip::Santander.new("xxxx", "xxxx", "xxxx") }
    
    context "given the client_id and client_secret" do
      it "fails without the digital certificate" do
        expect(santander.authenticate).not_to eql('201')
      end
    end
  end
end

4. 确认HTTParty加载正常

确保rails_helper.rb中没有排除HTTParty的加载,若有需要可在测试文件顶部显式添加require 'httparty'(通常require 'rails_helper'会自动加载所有Gem)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:57:00