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
相关产品推荐
相关产品推荐

