Martin Martin - 4 months ago 33
C++ Question

Adding expected calls in a loop

This is what I want to achieve. In my test fixture I want to call a helper functions with a parameter

n
to tell the test fixture how many initialization sequences should be expected. Some parameters used in the sequences are stored in three
std::vector
containers;
fileDescriptor, handle, selectionObject
.

What I have written is this:

void MyTest::init_Ok(uint32_t n)
{
for (uint32_t i = 0; i < n; ++i)
{
fileDescriptor.push_back(i); // FDs starting at 0
handle.push_back(reinterpret_cast<void*>(18 + i)); // handles starting at 18
selectionObject.push_back(555 + i); // SOs starting at 555

EXPECT_CALL(MyMockApi::getApi(), initialize(Pointee(nullptr), StrEq("InitString"), MyMatcher()))
.WillOnce(DoAll(SetArgPointee<0>(handle[i]),
Return(INIT_OK)));
EXPECT_CALL(MyMockApi::getApi(), selectionObjectGet(handle[i], Pointee(nullptr)))
.WillOnce(DoAll(SetArgPointee<1>(selectionObject[i]),
Return(SELECTION_OK)));
EXPECT_CALL(MyMockApi::getApi(), finalize(handle[i]))
.WillOnce(Return(FINAL_OK));
}
}


I know why it's not working. It is expected that all calls to
initialize
will be identical but yet I want to perform different actions (parameter depending on loop counter
i
) for the first, second, third, ..., nth call. The current implementation will only expect one call to
initialize
no matter parameter
n
. Is it possible to fix this and keep it a loop somehow, or do I have to add the actions with a
WillOnce
line for each
i
? This would mean i have to check
n
and add different number of
WillOnce
lines for different possible values of
n
, which i really want to avoid.

Answer

One way could be to use Invoke. You can write a function which will have access to the handles container and a running member/static variable(lets say counterVar) which will indicate the number of times the function is hit. Based on the value of counterVar, you can decide the logic.

.WillRepeatedly(Invoke(<your function>))

Something like:

EXPECT_CALL(MyMockApi::getApi(), initialize(Pointee(nullptr), StrEq("InitString"), MyMatcher()))
      .WillRepeatedly(Invoke(successfulInitialize));

ReturnCode successfulInitialize(void* op, std::string msg)
{
   static int counterVar = 0;
   *op = handles[counterVar++];
   return INIT_OK;
}