Search code examples
c++googletestgooglemock

Mock non-virtual method giving compilation error


I need to write the gtest to test some existing code that has a non-virtual method, hence I am testing using the below source, but I am getting the compilation error

package/web/webscr/sample_template_class3.cpp: In function âint main()â: package/web/webscr/sample_template_class3.cpp:64: error: âclass Templatemyclassâ has no member named âgmock_displayâ

sample_template_class3.cpp

#include <iostream>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

using namespace std;

template < class myclass>
class Templatemyclass
{
    private:
            myclass T;
    public :

        void display()
        {
            T.display();
        }

};

class Test
{
    public:
         void display()
        {
            cout<<"Inside the display Test:" <<endl;
        }

};

class MockTest

{
    public:
                MOCK_METHOD0(display,void());
};

class FinalTest
{
        public:
                        void show( Templatemyclass<Test> t)
                        {
                                t.display();
                                cout<<"Inside the display FinalTest:" <<endl;
                        }



};
int main()
{


FinalTest test1;
Templatemyclass<Test> obj1;
Templatemyclass<MockTest> obj2;
EXPECT_CALL(obj2,display()).Times(1);
test1.show(obj1);

return 1;
}

Solution

  • There are a couple of issues in your code. I have changed it below and commented the code by way of explanation. If this is not clear enough, add a comment and I'll try and explain further.

    #include <iostream>
    #include <gtest/gtest.h>
    #include <gmock/gmock.h>
    
    using namespace std;
    
    template <class myclass>
    class Templatemyclass {
     private:
      // Hold a non-const ref or pointer to 'myclass' so that the actual
      // object passed in the c'tor is used in 'display()'.  If a copy is
      // used instead, the mock expectations will not be met.
      myclass* T;
     public :
      // Pass 'myclass' in the c'tor by non-const ref or pointer.
      explicit Templatemyclass(myclass* t) : T(t) {}
      void display() { T->display(); }
    };
    
    class Test {
     public:
      void display() { cout << "Inside the display Test:" << endl; }
    };
    
    class MockTest {
     public:
      MOCK_METHOD0(display, void());
    };
    
    class FinalTest {
     public:
      // Templatise this function so we can pass either a Templatemyclass<Test>
      // or a Templatemyclass<MockTest>.  Pass using non-const ref or pointer
      // again so that the actual instance with the mock expectations set on it
      // will be used, and not a copy of that object.
      template<class T>
      void show(T& t) {
        t.display();
        cout<<"Inside the display FinalTest:" <<endl;
      }
    };
    
    int main() {
      Test test;
      Templatemyclass<Test> obj1(&test);
    
      MockTest mock_test;
      Templatemyclass<MockTest> obj2(&mock_test);
      EXPECT_CALL(mock_test,display()).Times(1);
    
      FinalTest test1;
      test1.show(obj1);
      test1.show(obj2);
    
      return 0;
    }
    

    The following could possibly simplify the case:

    #include <iostream>
    #include <gtest/gtest.h>
    #include <gmock/gmock.h>
    
    template <class myclass>
    class Templatemyclass {
     public:
      myclass T;
      void show() const { T.display(); }
    };
    
    struct Test {
      void display() const { std::cout << "Inside the display Test:\n"; }
    };
    
    struct MockTest {
      MOCK_CONST_METHOD0(display, void());
    };
    
    int main() {
      Templatemyclass<Test> obj1;
      obj1.show();
    
      Templatemyclass<MockTest> obj2;
      EXPECT_CALL(obj2.T, display()).Times(1);
      obj2.show();
    
      return 0;
    }