如何从模拟方法返回对矢量项的const引用?

时间:2018-12-09 15:46:32

标签: c++ googlemock

我正在使用数据库对象作为依赖项来为类编写基于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生成的包装器会在此过程中某处从lambda返回的引用中复制一个副本,但是很难遵循这些混乱的代码。无论如何,如何在不更改界面的情况下实现所需的功能?

1 个答案:

答案 0 :(得分:2)

正如this answer所阐明的,TEST_DATA.at(i)表达式的类型为Entry,而不是const Entry&,因此lambda的返回类型被推导为非引用,造成问题。

通过明确说明lambda的返回类型来解决此问题:

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