Suppose I have a class
class MinorClass{
virtual void NestedFunction(){...};
};
that is used to as following in another class
class MajorClass{
public:
MajorClass(unique_ptr<MinorClass>&& input)
: minor_class{std::move(input)}{};
...
std::unique_ptr<MinorClass> minor_class;
void foo(){minor_class->NestedFunction();};
}
In gtest I want to create a test that tests if the NestedFunction()
is called within foo()
. For this I implement a mock Class in gtest:
class MockMinorClass : public MinorClass
{
public:
MOCK_METHOD(void, NestedFunction, (), (override));
};
and then I implement a test such as:
TEST(MajorClassTest, TestingNestedCalls)
{
// given
auto minor_class = std::make_unique<MinorClass>(new MockMinorClass());
auto major_class = MajorClass(std::move(minor_class));
// then
EXPECT_CALL(*(major_class.minor_class), NestedFunction()).Times(1);
major_class.Init();
}
But I am getting the error MinorClass
has no member named 'gmock_NestedFunction`.
How to test if an instance method is called from another class instance through a smart pointer to it?
EDIT
This a minimum verifiable working example that uses the current answer. In this example, the test is failing because the function is not called in reality.
A difference with the answer: the destructor must be defined virtual, otherwise memory leak of the mock object happens with the error:
ERROR: this mock object (used in test MajorClassTest.TestingNestedCalls) should be deleted but never is.
#include <gtest/gtest.h>
#include <gmock/gmock.h>
class MinorClass{
public:
virtual void NestedFunction(){
std::cerr<<"Invoked MinorClass::NestedFunction()\n";
};
virtual ~MinorClass()=default;
};
class MajorClass{
public:
MajorClass(std::unique_ptr<MinorClass>&& input)
: minor_class{std::move(input)}{};
std::unique_ptr<MinorClass> minor_class;
void foo(){
std::cerr<<"Invoked MajorClass::foo()\n";
minor_class->NestedFunction();
};
};
class MockMinorClass : public MinorClass
{
public:
MOCK_METHOD(void, NestedFunction, (), (override));
};
TEST(MajorClassTest, TestingNestedCalls)
{
auto minor_class = std::make_unique<MockMinorClass>();
// Keep the reference to the instance of `MockMinorClass`.
auto* mock_minor = minor_class.get();
auto major_class = MajorClass(std::move(minor_class));
EXPECT_CALL(*mock_minor, NestedFunction());
}