Home > other >  Virtual method in C fails to get mocked. What am I missing here?
Virtual method in C fails to get mocked. What am I missing here?

Time:02-03

I have following setup:

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

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

  private:
    Backends backends_;
};

Implementation:

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

Then a piece of function in another place which uses it as:

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

Now I am trying to test Process with any call to GetData being mocked, as following:

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

What is wrong in this? I am seeing that actual implementation of GetData is getting called and I am seeing that message Yikes! This was called too. Since GetData is a virtual function, it should get the empty vector of Data back as result from the mocked one. Why is that not happening?

Finally the test crashes because backend doesn't have initialization of its members.

CodePudding user response:

The function doesn't use mock object at all:

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

Regardless whether you create a MockDataFetcher the Process function create local DataFetcher and uses it - not the mock that you have created in test case - you need to provide it somehow to the Process function.

CodePudding user response:

From your declaration:

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

GetData() returns an object.

Yet, in Process(),

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

}

The variable 'data' cannot be a reference, since the object it refers to has literally no life span. Any attempt to use 'data' will result in undefined behaviour.

  • Related