如何模拟任意大小的向量?

How to mock a vector of an arbitrary size?

我定义了一个 class,它接受一个 vector 作为构造函数的输入参数,并提供了一个使用 vectorsize() 函数的方法:

class Foo {
  vector<int> storedVector;

  public:
    explicit Foo(vector<int>);
    bool isSizeGreaterThanInt();
}

Foo::Foo(vector<int> inputVector) : storedVector(std::move(inputVector)) {  }

bool Foo::isSizeGreaterThanInt()
{
  if (storedVector.size() > INT32_MAX) { return true; }

  return false;
}

现在我想测试这个class的isSizeGreaterThanInt()方法。作为该测试的一部分,我还想验证实现 return 内部的 size() 调用是传递给构造函数的向量的 size() 而不是其他 vector/some其他尺码。

我分别使用 gtestgmock 作为我的测试和模拟框架。

我所有尝试创建 vector<int> 的模拟,将 size() 函数模拟为 return 特定值似乎都失败了,我的模拟的最新版本如下:

template <typename VectorValueType>
class MockVector : public std::vector<VectorValueType> {
  public:
    MOCK_CONST_METHOD0_T(size, size_t());
};

TEST(Test,TestCase)
{
  size_t fakeSize = static_cast<size_t>(INT32_MAX) + 1;
  MockVector<int> mockVector;
  EXPECT_CALL(mockVector, size()).WillRepeatedly(testing::Return(fakeSize));

  size_t testSize = mockVector.size(); // here the value is correct

  Foo foo (mockVector);

  // if I debug here and check the size of the vector now stored in foo - it's 0.

  ASSERT_EQ(true, foo.isSizeGreaterThanInt());
}

我担心 std::move 和移动行为,所以我尝试通过引用传递 inputVector,尝试传递指针,尝试存储 vector<int>& storedVector 而不是使用值成员...没有成功了。

我想做的事情可行吗?我做错了什么?

更新

其中一位评论者认为这是由于将 MockVector 类型拼接到 vector<int> 中而发生的,并且当它拼接时不再调用模拟方法......但是,我应该如何去嘲笑矢量? C++ STL 中没有 vector<> 的接口,所以我不能将其作为构造函数的参数...

更新 2

正如其中一个答案所建议的那样,是的,我可以在 Foo 中添加一个 getSize() 并模拟它......但它改变了 Foo 的合同并且我' d 不想那样做。此外,如果我愿意这样做,我仍然需要模拟我的 vector 来测试 getSize() 行为,以确保 getSize() 真正 return 是 size() 的矢量,而不是其他一些值。基本上,这样做只是将相同的问题转移到不同的地方。

更新 3

是的,理论上我可以在我的测试中创建一个向量,只是将它传入而不是模拟它。这里的问题是,要测试上述特定行为,我需要创建一个包含 (INT32_MAX + 1) 元素的 vector,这对于测试来说非常昂贵 (resources/time/memory) .

您不能模拟 std::vector 的方法,因为 GoogleTest 中的模拟系统基于多态性,并且 std::vector 未准备好用于多态性 - none 它的方法是 virtual。由于 size() 方法不是 virtual,因此永远不会调用模拟实现,GoogleMock 无法注册该调用或执行操作。

测试的唯一方法是将大小为 INT32_MAX 的向量传递给被测试的 class(也许这个测试应该默认禁用,只在 CI 中启用envireonment) 或为 std::vector 创建一个包装器,它将在其接口中包含 virtual 方法。