I've defined a class that accepts a vector as a constructor input parameter and provides a method that uses vector's size() function:
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;
}
Now I would like to test the isSizeGreaterThanInt() method of this class. As part of that test I want to also validate that the size() call inside of the implementation returns the size() of the vector passed into the constructor and not some other vector/some other size.
I'm using gtest and gmock as my testing and mocking framework respectively.
All my attempts to create a mock of vector<int> which mocks the size() function to return a specific value seem to fail, my latest version of the mock is as follows:
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());
}
I had concerns about std::move and move behavior so I tried passing inputVector by reference, tried passing pointers, tried storing vector<int>& storedVector instead of having a value member... nothing worked.
Is what I'm trying to do possible? What am I doing wrong?
Update
One of the commenters suggested it happens due to splicing of the MockVector type into vector<int>, and when it's spliced the mocked methods are no longer called... but still, how should I go about mocking the vector? There is no interface for vector<> in C++ STL, so I can't make that a parameter to the constructor...
Update 2
As suggested in one of the answers, yes, I can add a getSize() to Foo and mock that... But it changes Foo's contract and I'd prefer not to do that. Furthermore, if I was willing to do that, I still would need to mock my vector to test the getSize() behavior to ensure that getSize() truly returns the size() of the vector and not some other value. Basically, doing that is just moving the same problem to a different place.
Update 3
Yes, theoretically I can create a vector in my test, just pass it in and not mock it. The issue here is that to test the specific behavior described above I'll need to create a vector with (INT32_MAX + 1) elements in it, which is prohibitively expensive (resources/time/memory) for the test.