I am writing googletest/googlemock-based unit tests for a class using a database object as a dependency, so I decided to mock the database. It provides read-only access to items of type Entry
based on an index:
struct Entry {
int x, y;
};
class DbIface {
public:
virtual ~DbIface() {}
virtual int count() const = 0;
virtual const Entry& entry(const int idx) const = 0;
};
class DbMock : public DbIface {
public:
MOCK_CONST_METHOD0(count, int());
MOCK_CONST_METHOD1(entry, const Entry&(const int idx));
};
I want to specify some predefined data for the test and make the mock return that:
const std::vector<Entry> TEST_DATA = { { 0, 1 }, { 2, 3 }, { 4, 5 } };
DbMock mock;
EXPECT_CALL(mock, count).WillOnce(Return(TEST_DATA.size()));
EXPECT_CALL(mock, entry).WillOnce(Invoke([](int i) { return TEST_DATA.at(i); }));
However, I am getting an error on the last EXPECT_CALL
:
warning C4172: returning address of local variable or temporary
I expect the GMock-generated wrapper makes a copy from the reference returned by the lambda somewhere along the way, but it's difficult to follow in that mess of code. In any case, how do I achieve what I need without changing the interface?
As clarified by this answer, the type of the TEST_DATA.at(i)
expression is Entry
, not const Entry&
, so the lambda has its return type deduced to be non-reference, causing the problem.
This is fixed by explicitly stating the return type of the lambda:
EXPECT_CALL(mock, entry).WillOnce(Invoke([](int i) -> const Entry& { return TEST_DATA.at(i); }));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With