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

