Hi!
I was implementing a mock factory function that would generate new objects, themselves mocks, with an implementation that would have all objects return a reference to the same object:
MyMock::MyMock(Thing thing) {
// ...
ON_CALL(*this, SomeFunction(_))
.WillByDefault(Invoke([thing] {
auto* object = new MockObject;
// GetThing returns a const Thing&.
EXPECT_CALL(*object, GetThing()).WillRepeatedly(ReturnRef(thing));
return object;
}));
}
I expected the first lamba, capturing thing here by-value would stick around somewhere in the mock class, get invoked whenever SomeFunction was called, and let the mocked object it generated return a reference to it.
I was, however, unable to get it to work. Whenever I referenced values in the Thing returned by GetThing, they'd all be wildly wrong.
I've traced the reason down to InvokeHelper::Invoke taking its function parameter by-value, copying my (lambda) functor on invocation of SomeFunction, and making GetThing return a reference to the thing inside the temporary functor.
see:
I've only seen lambda-friendly template functions like this take their function argument by rvalue-reference (i.e. Function&& in this case) and an informal change and rebuild of that call fixed the issue. (I'm of course not keeping it like that).
Is the copying of the functor during invocation a mistake or intended behavior?
I've worked around it for now, by putting the Thing somewhere else, but it seems to me like this should work.
Best regards,
Oskar