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

如何用GMock对循环内调用的函数使用Expect Call测试?

问题分析与修正方案

你的测试代码存在几个关键问题,导致GMock无法正确捕获调用并验证重试逻辑:

1. Mock对象不一致

你同时使用了*requester和*mock_requester两个不同的Mock实例,但实际业务逻辑里应该依赖同一个Mock对象,这会导致调用无法被正确记录。

2. 调用次数匹配错误

你的重试逻辑总共会触发4次send_request调用,但你只设置了Times(1),这会直接触发GMock的调用次数断言失败。

3. 参数匹配器使用错误

send_request(HttpResponse)这种写法是用默认构造的HttpResponse对象做精确匹配,而实际业务代码中传入的请求对象大概率和这个默认对象不相等,导致调用不被Mock捕获。应该使用通配符匹配器_来匹配任意参数。

4. 调用顺序与行为绑定错误

重试逻辑是每次调用send_request后获取response,所以需要把send_request的调用和response的返回绑定,确保每次send_request调用后都能拿到错误响应。


修正后的测试代码示例

假设你的Mock类定义大致如下:

class MockRequester {
public:
    MOCK_METHOD(int, send_request, (const HTTPRequest&), ());
    MOCK_METHOD(HttpResponse*, response, (), ());
};

修正后的测试代码:

// 创建单个Mock实例
MockRequester mock_requester;

// 构造错误响应
HttpResponse error_response;
error_response.status(HTTPSTATUS_NOT_FOUND);

// 配置Mock:send_request被调用4次,每次返回0(假设0表示请求发送成功但响应错误)
EXPECT_CALL(mock_requester, send_request(_))
    .Times(4)
    .WillRepeatedly(Return(0));

// 配置Mock:每次调用response()都返回错误响应
EXPECT_CALL(mock_requester, response())
    .Times(4)
    .WillRepeatedly(Return(&error_response));

// 验证最终抛出异常
EXPECT_THROW(loop_function("hello", true, mock_requester), std::runtime_error);

额外说明

  • 如果send_request的返回值代表请求发送是否成功(比如非0表示发送失败),你需要根据实际逻辑调整Return()的参数。
  • 确保loop_function接收的是Mock实例的引用或指针,而不是创建新的真实对象。
  • 若需要严格控制调用顺序(比如必须先调用send_request再调用response),可以使用InSequence:
InSequence seq;
for (int i = 0; i < 4; ++i) {
    EXPECT_CALL(mock_requester, send_request(_)).WillOnce(Return(0));
    EXPECT_CALL(mock_requester, response()).WillOnce(Return(&error_response));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 19:20:53