Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return const reference to vector item from a mocked method?

Tags:

c++

googlemock

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?

like image 948
neuviemeporte Avatar asked Sep 07 '25 11:09

neuviemeporte


1 Answers

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); }));
like image 76
neuviemeporte Avatar answered Sep 10 '25 07:09

neuviemeporte