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.