Google GMock EXPECT_CALL提示mock方法从未被调用问题
Mock方法期望未触发、真实函数被执行问题排查
相关业务代码
#define NULL_POINTER (int)1003 class MyClass { int curl_fetch_url(CURL *curl, const char *url, response_t *presponse) { // 注:原代码此处存在孤立的NULL_POINTER无效语句、首行Class大写问题,均属于笔误 if (curl == NULL || url == NULL || NULL == presponse) { return NULL_POINTER; } }
测试用例代码
TEST(curl_fetch_url_1) { curl_global_init(CURL_GLOBAL_ALL); CURL *curl = curl_easy_init(); int expected_ret = NULL_POINTER; CurlMocker mock; EXPECT_CALL(mock, curl_fetch_url(curl, "", NULL)).WillOnce(Return(NULL_POINTER)); int actual_ret = curl_fetch_url(curl, "", NULL); ASSERT_EQ(actual_ret, expected_ret); curl_easy_cleanup(curl); curl_global_cleanup(); }
问题表现
运行用例时真实的curl_fetch_url函数被执行,actual_ret返回值和预期的NULL_POINTER(值1003)完全一致,但测试框架抛出如下错误:
EXPECT_CALL(mock, curl_fetch_url(curl, "", NULL)).WillOnce(Return(NULL_POINTER))... Expected: to be called once Actual: never called - unsatisfied and active
已经在curl_fetch_url内部加打印确认真实函数确实执行,无法定位根因,可按以下顺序排查:
- 先排查最核心的调用逻辑错误:
EXPECT_CALL设置的是mock对象的方法调用期望,但你代码里是直接调用全局/类作用域下的真实curl_fetch_url函数,全程没有调用mock对象的同名方法,框架自然统计不到调用记录,期望永远不会被满足。这类问题是Mock框架新手最容易踩的坑:EXPECT_CALL不会自动替换全局同名函数的实现,它只会监听你创建的mock对象实例的方法调用。要让Mock生效,必须通过依赖注入、模板参数注入等方式,把被测代码中调用的curl_fetch_url实现替换为mock对象的方法,不能硬编码直接调用真实实现。 - 检查待Mock的方法是否符合框架要求:如果使用的是GTest配套的GMock框架,要Mock的成员方法必须定义为
virtual,且Mock类要公开继承定义该方法的基类,否则框架无法通过多态机制替换方法实现,打桩逻辑不会生效。 - 检查方法签名是否完全匹配:对比Mock类中
curl_fetch_url的方法签名和真实方法的签名,确认返回值、参数类型、参数顺序、const修饰符、引用修饰符完全一致,只要有一个细节不匹配,你打桩的就是另一个完全独立的重载方法,自然不会被触发。 - 检查编译链接配置:如果使用的是链接期替换的非侵入式Mock方案(比如ld --wrap、FakeIt等),需要确认Mock相关的目标文件/库在链接时的顺序排在真实实现的目标文件之前,否则链接器会优先链接真实函数实现,Mock逻辑完全不会被加载。
- 先修正代码中的显式语法错误:你贴出的业务代码里,
curl_fetch_url函数开头有一行孤立的NULL_POINTER语句、类定义关键字首字母大写,都属于非法语法,会直接导致编译行为不符合预期,先修正这些笔误残留再做后续调试。
内容的提问来源于stack exchange,提问作者Vikas
相关产品推荐
相关产品推荐

