You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:15:20