Как вернуть константную ссылку на векторный элемент из смоделированного метода? - PullRequest
0 голосов
/ 09 декабря 2018

Я пишу модульные тесты на основе googletest / googlemock для класса, использующего объект базы данных в качестве зависимости, поэтому я решил смоделировать базу данных.Он предоставляет доступ только для чтения к элементам типа Entry на основе индекса:

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));
};

Я хочу указать некоторые предопределенные данные для теста и сделать макет возврата, который:

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); }));

Тем не менее, я получаю сообщение об ошибке в последнем EXPECT_CALL:

предупреждение C4172: возвращение адреса локальной переменной или временное

Я ожидаю GMock-сгенерированная оболочка создает копию из ссылки, возвращаемой лямбда-кодом где-то по пути, но в этом беспорядке кода трудно следовать.В любом случае, как мне добиться того, что мне нужно, без изменения интерфейса?

1 Ответ

0 голосов
/ 10 декабря 2018

Как пояснил в этом ответе , тип выражения TEST_DATA.at(i) равен Entry, а не const Entry&, поэтому лямбда-тип имеет тип возвращаемого значения, не являющийся ссылочным, что вызывает проблему,

Это исправлено явным указанием типа возврата лямбды:

EXPECT_CALL(mock, entry).WillOnce(Invoke([](int i) -> const Entry& { return TEST_DATA.at(i); }));
...