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

如何使用gmock mock指定大小的vector完成C++类方法单元测试?

问题根因

首先明确两个核心错误:

  • std::vector的size()方法不是虚函数,即使继承子类覆写该方法,也不存在运行时多态效果,父类指针/引用调用该方法永远会走原生std::vector的实现
  • 你把MockVector对象传给接收std::vector<int>的构造函数时,会发生对象切片,子类的mock相关数据会被完全截断,Foo内部存储的就是原生std::vector对象,mock逻辑自然不会生效

你之前尝试改引用、传指针都没用,核心原因就是没有虚函数的前提下,父类类型的引用/指针永远不会调用子类覆写的方法。


可行的解决方案

推荐使用**编译期多态(模板)**实现mock,完全不需要修改Foo的对外契约,业务代码无侵入:

步骤1:修改Foo为模板类,设置默认模板参数

// 新增模板参数,默认值为std::vector<int>,原有业务代码无需任何修改
template <typename VectorType = std::vector<int>>
class Foo {
  VectorType storedVector;

  public:
    explicit Foo(VectorType inputVector);
    bool isSizeGreaterThanInt();
};

template <typename VectorType>
Foo<VectorType>::Foo(VectorType inputVector) : storedVector(std::move(inputVector)) {  }

template <typename VectorType>
bool Foo<VectorType>::isSizeGreaterThanInt()
{
  return storedVector.size() > INT32_MAX;
}

修改后业务代码仍可以按原来的方式调用Foo<>(省略模板参数就会用默认的std::vector<int>),对外接口完全没有变化,不会修改原有契约。

步骤2:调整测试代码,传入MockVector作为模板参数

template <typename VectorValueType>
class MockVector {
  public:
    // 不需要继承std::vector,只需要实现你用到的方法即可
    MOCK_CONST_METHOD0_T(size, size_t());
    // 如果Foo用到其他vector方法,在这里补充mock即可
};

TEST(FooTest, SizeGreaterThanInt32MaxReturnsTrue)
{
  const size_t fakeLargeSize = static_cast<size_t>(INT32_MAX) + 1;
  MockVector<int> mockVector;
  // 可以加Times(1)验证size方法确实被调用了1次
  EXPECT_CALL(mockVector, size()).WillOnce(testing::Return(fakeLargeSize));

  // 传入MockVector作为模板参数,Foo内部存储的就是MockVector对象,不会切片
  Foo<MockVector<int>> foo(std::move(mockVector));
  ASSERT_TRUE(foo.isSizeGreaterThanInt());
}

这个方案还能直接验证isSizeGreaterThanInt确实调用了传入vector的size()方法,只需要调整EXPECT_CALL的Times参数即可,完全满足你的测试需求。


其他可选方案

如果完全不想修改Foo的代码,也可以使用编译器级别的打桩方案,比如GCC的--wrap参数 hook 掉std::vector<int>::size()的实现,但这种方案和编译器强绑定,兼容性差,远不如模板方案通用易维护。

内容的提问来源于stack exchange,提问作者Philip P.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:15:01