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

RSpec教程:如何测试方法内部对其他类方法的调用?

验证Foo.get_events对Client.get_events的调用

要测试Foo.get_events(date)是否正确调用Client.get_events(user_id, date),核心思路是用模拟对象替代真实的Client实例,然后跟踪这个模拟对象的方法调用情况。以下是具体实现方案:

先修正一个代码问题

你提供的Client类中get_events方法没有定义参数,但Foo里调用时传递了user[:id]和date两个参数,这会导致运行时错误。先修正Client的方法定义:

class Client
  def get_events(user_id, date)
    # API调用逻辑
  end
end

使用RSpec编写测试(Ruby生态常用方案)

利用RSpec的模拟功能,创建一个严格的Client模拟对象,验证方法调用的参数和次数:

RSpec.describe Foo do
  let(:user) { { id: 123 } } # 可替换为真实User实例,只要能获取id即可
  let(:client_double) { instance_double(Client) } # 严格模拟Client类,确保方法存在
  let(:foo) { Foo.new(user: user, client: client_double) } # 假设Foo初始化时接收user和client参数
  let(:test_date) { Date.today }

  it "调用client.get_events并传入正确的用户ID和日期" do
    # 预先设定预期:模拟对象的get_events方法会被传入指定参数调用
    expect(client_double).to receive(:get_events).with(user[:id], test_date)

    # 执行待测试的方法
    foo.get_events(test_date)
  end
end
  • instance_double是严格模拟,会检查Client类是否真的存在get_events方法且参数匹配,避免测试假阳性。
  • 测试逻辑:先声明对模拟对象的调用预期,再执行目标方法,RSpec会自动验证预期是否达成。

如果你用Minitest测试

如果项目使用Minitest,可通过Minitest::Mock实现同样的验证:

require "minitest/autorun"

class FooTest < Minitest::Test
  def test_get_events_calls_client_method_with_correct_args
    user = { id: 123 }
    client = Minitest::Mock.new
    foo = Foo.new(user: user, client: client)
    test_date = Date.today

    # 设定预期:调用get_events,参数为user[:id]和test_date,返回值可设为nil(不关心返回值时)
    client.expect(:get_events, nil, [user[:id], test_date])

    foo.get_events(test_date)

    # 验证所有预期都被执行
    client.verify
  end
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 04:50:39