如何在gmock中搭配派生类std::shared_ptr使用SaveArgPointee
问题原因说明
首先纠正两个认知误区:
- 用
SaveArg保存shared_ptr类型参数完全不存在悬垂指针风险,shared_ptr拷贝时会自动增加引用计数,只要接收变量在作用域内,指向的对象就不会被提前释放 SaveArgPointee是对参数解引用后保存值,要求指向的类型可拷贝赋值,你之前报错要么是类型不匹配,要么是消息类没有可访问的拷贝构造/赋值运算符,要么是没有传入变量的指针地址
推荐解决方案:直接用SaveArg保存shared_ptr
这是最稳妥、无额外限制的方案,直接匹配sendMessage的参数类型即可:
TEST(SomeClassTest, writesMessageToSocket){ MockTcp mockTcp; SomeClass sc(mockTcp); // 声明和sendMessage参数同类型的shared_ptr即可 std::shared_ptr<BaseMessage> msgArg; // SaveArg<0>表示保存第0位参数本身,注意要传入变量的指针 EXPECT_CALL(mockTcp, sendMessage(_)).Times(1).WillOnce(::testing::SaveArg<0>(&msgArg)); const auto derivedMsg = std::make_shared<DerivedMessage>(); sc.writeDataToRemote(derivedMsg); // 后续校验逻辑示例 auto derivedArg = std::dynamic_pointer_cast<DerivedMessage>(msgArg); ASSERT_NE(derivedArg, nullptr); // 可以继续校验derivedArg的data()返回值、内部成员等逻辑 }
备选方案:用SaveArgPointee保存对象副本
如果你确实需要保存消息对象的独立副本,需要保证DerivedMessage可拷贝,代码实现如下:
TEST(SomeClassTest, writesMessageToSocket){ MockTcp mockTcp; SomeClass sc(mockTcp); // 必须用具体子类类型声明变量,不能用抽象基类BaseMessage DerivedMessage msgArg; EXPECT_CALL(mockTcp, sendMessage(_)) .Times(1) .WillOnce(::testing::SaveArgPointee<0>(&msgArg)); const auto derivedMsg = std::make_shared<DerivedMessage>(); sc.writeDataToRemote(derivedMsg); // 直接校验msgArg的内容即可 }
内容的提问来源于stack exchange,提问作者El_Mewo
相关产品推荐
相关产品推荐

