如何用GMock创建支持shared_ptr的模板化自定义匹配器
问题描述
我想使用GoogleTest中的WhenDynamicCastTo<T>(m)匹配器,但需要动态转换的对象是shared_ptr类型,而原生的WhenDynamicCastTo并不支持智能指针。
我尝试自行编写支持智能指针的版本,但不清楚如何创建模板化匹配器,以下写法无法正常工作:
template <typename To> MATCHER_P(WhenDynamicPointerCastTo<To>, matcher, "") { // 这里想用std::dynamic_pointer_cast }
目前我通过以下方式实现了需求,但希望将其封装为一个独立匹配器:
template <typename To> std::shared_ptr<const To> dynamic_smart_pointer_cast( const std::shared_ptr<const parent>& p) { return std::dynamic_pointer_cast<const To>(p); } EXPECT_CALL(*mock_, func( ::testing::ResultOf( dynamic_smart_pointer_cast<child>, ::testing::Pointee(...))));
解决方案
要实现支持shared_ptr的动态转换匹配器,需遵循GoogleTest的MATCHER_P宏模板语法规范,正确写法如下:
模板化匹配器实现
template <typename To> MATCHER_P(WhenDynamicPointerCastTo, matcher, "") { // 对输入的shared_ptr执行动态转换 auto casted_ptr = std::dynamic_pointer_cast<const To>(arg); // 转换成功时,用传入的匹配器验证目标指针,同时传递匹配结果信息 return casted_ptr != nullptr && ExplainMatchResult(matcher, casted_ptr, result_listener); }
核心要点
- 模板参数写法:MATCHER_P的模板参数无需嵌入宏名称,直接在
template <typename To>声明后使用宏即可,模板参数由调用时指定或推导。 - 匹配逻辑完整性:先判断动态转换是否成功,再用
ExplainMatchResult将子匹配器的验证结果(包括失败信息)传递给GoogleTest的结果监听器,确保错误提示正常输出。 - 扩展性:如果需要支持非const的
shared_ptr,可以调整模板为std::shared_ptr<To>,或通过std::remove_const_t处理类型,也可编写重载版本覆盖const/非const场景。
使用示例
验证func接收的shared_ptr<parent>可动态转换为shared_ptr<child>,且转换后的对象满足指定条件:
EXPECT_CALL(*mock_, func( WhenDynamicPointerCastTo<child>( ::testing::Pointee(::testing::Property(&child::get_value, 42)) ) ));
这样就将原有的ResultOf逻辑封装成了独立匹配器,用法和原生WhenDynamicCastTo一致,更贴合GoogleTest的使用习惯。
内容的提问来源于stack exchange,提问作者av4625
相关产品推荐
相关产品推荐

