C++中的虚方法不能被嘲笑,我错过了什么?

thigvfpy  于 2023-02-06  发布在  其他
关注(0)|答案(2)|浏览(162)

我有以下设置:

Class DataFetcher {
  public:
    virtual ~DataFetcher() = default;
    explicit DataFetcher(const Backends& backends);

    virtual vector<Data> GetData(const vector<string>& q) const;

  private:
    Backends backends_;
};

实施:

vector<Data> DataFetcher::GetData(const vector<string>& q) {
  cout << "Yikes! This was called";
  ...
}

然后在另一个地方使用一个函数作为:

void Process(const Backends& backends) {
  DataFetcher data_fetcher(backends);
  ...
  const auto& data = data_fetcher.GetData(q);
  ...
}

现在,我尝试使用对GetData的任何调用进行模拟来测试Process,如下所示:

class MockDataFetcher : public DataFetcher {
  public:
    using DataFetcher::DataFetcher;
    MOCK_METHOD(vector<Data>, GetData, (const vector<string>& q), (const, override));
}

class ActualLogicTest : public ... {
  protected:
    Backends backends_;
}

TEST_F(ActualLogicTest, BasicOne) {
  MockDataFetcher mock_data_fetcher(backends_);
  vector<Data> data;
  ON_CALL(mock_data_fetcher, GetData).WillByDefault(Return(data));
  ...
  Process(backends_);
}

这是哪里出了问题?我看到GetData的实际实现被调用了,我也看到了消息Yikes! This was called。因为GetData是一个虚函数,它应该从被模拟的函数中获取空的Data向量作为结果。为什么没有发生呢?
最后,测试崩溃,因为后端没有初始化其成员。

wlsrxk51

wlsrxk511#

该函数根本不使用mock对象:

void Process(const Backends& backends) {
  DataFetcher data_fetcher(backends);
  ...
  const auto& data = data_fetcher.GetData(q);
  ...
}

无论您是否创建MockDataFetcherProcess函数都会创建本地DataFetcher并使用它--而不是您在测试用例中创建的mock--您需要以某种方式将其提供给Process函数。

h79rfbju

h79rfbju2#

从您的声明中:

virtual vector<Data> GetData(const vector<string>& q) const;

GetData()返回一个对象。
然而,在Process()中,

void Process(const Backends& backends) {
  DataFetcher data_fetcher(backends);
  ...
  const auto& data = data_fetcher.GetData(q);  // BUG!! Why is data a reference?

}

变量“data”不能是引用,因为它所引用的对象实际上没有生命期。任何使用“data”的尝试都将导致未定义的行为。

相关问题