Googletest EXPECT_CALL未记录调用:tagcache()断言失败排查
解决测试断言
Resource::tagcache()未被调用的问题 这种情况我之前排查过好几次,明明代码里已经走到了调用逻辑,但测试就是报从未调用,大概率是mock对象的关联或者测试细节没处理对,咱们一步步来排查:
1. 先确认mock对象是不是对应上了
首先要搞清楚:你在测试里设置EXPECT_CALL的那个Resource实例,是不是实际被传入tagResource/addToResource方法的那个对象?
- 如果测试中你创建了一个真实的
Resource实例,或者另一个没设置期望的mock实例,那断言肯定会失败——你监听的是错的对象啊! - 举个例子,用Google Test/Mock的话,必须确保注入到
tagResource方法里的,是你已经配置好期望的那个MockResource*,不能是临时new的其他实例。
2. 检查tagcache()的返回值是否影响mock监听
看你的代码是r->tagcache()->add(...),这里要注意两个点:
- 如果
tagcache()返回的是智能指针(比如std::unique_ptr<TagCache>),你得确保mock的是这个智能指针指向的对象的add方法,同时要正确mocktagcache()的返回行为——让它返回你已经设置好期望的mock缓存对象。 - 如果
tagcache()返回的是临时对象的引用,那mock也会失效,因为你监听的对象和实际调用的不是同一个。
3. 走一遍代码的条件分支,确认没被跳过
把你的代码逻辑拆开来检查:
void TagModel::tagResource(Tag *tag, Resource *r) { if ( tag ){ tag->addToResource(r); } } void Tag::addToResource(Resource *r) { if ( !r ){ return; } addToResource(r->id()); r->tagcache()->add(this->id(),...); }
要确认:
- 传入的
tag不是nullptr,否则tag->addToResource(r)根本不会执行 - 传入的
r不是nullptr,否则addToResource直接return,到不了tagcache()那一步 addToResource(r->id())这个方法会不会抛出异常?如果抛异常,后面的r->tagcache()->add(...)就被跳过了
4. 检查mock期望的设置时机
如果你是在调用tagResource之后才设置的EXPECT_CALL,那肯定会失败!必须在触发方法调用之前就把所有mock期望配置好。
5. 排除对象拷贝/重定向的问题
虽然你的代码里都是指针传递,但还是要确认:Resource对象在传递过程中有没有被拷贝?如果是值传递的话,你监听的原始对象的方法自然不会被调用——不过这个可能性在你的代码里比较低,但可以快速排查下。
附一个正确的Google Test/Mock示例参考
TEST(TagModelTest, TagResourceTriggersTagCacheUpdate) { // 创建所有需要的mock对象 auto mock_tag = std::make_unique<MockTag>(); auto mock_resource = std::make_unique<MockResource>(); auto mock_tag_cache = std::make_unique<MockTagCache>(); // 设置期望:调用mock_resource的tagcache()时返回mock_tag_cache EXPECT_CALL(*mock_resource, tagcache()) .WillOnce(testing::Return(mock_tag_cache.get())); // 设置期望:mock_tag_cache的add方法至少被调用一次 EXPECT_CALL(*mock_tag_cache, add(testing::_, testing::_)) .Times(testing::AtLeast(1)); // 执行测试方法 TagModel model; model.tagResource(mock_tag.get(), mock_resource.get()); }
内容的提问来源于stack exchange,提问作者user2366975
相关产品推荐
相关产品推荐

