0

I am running into a problem about mocking a non-virtual method that need your help. I referred to the link: Mock non-virtual method giving compilation error

I understood what they did. But I have an advanced question. Assume that I have:

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

using ::testing::Invoke;
using ::testing::NiceMock;

template <class myclass> class Templatemyclass {
 public:
  myclass T;
  void show() ;
};

template <class myclass> void Templatemyclass<myclass>::show()
{
    T.show_text();
}

struct Test {

  void display()  { std::cout << __func__<<":-->Inside the display Test\n"; }

  void show_text()  {
      display(); // HOW to re-route it to my_display() ? (>.<)
  }
};

struct MockTest {
  MOCK_CONST_METHOD0(display, void());
  MOCK_CONST_METHOD0(show_text, void());
};

void my_display(){
    { std::cout <<__func__<<":-->Outside the display Test\n"; }
}

int main() {
  //NiceMock<Templatemyclass<Test> > obj1;
  //obj1.show();

  NiceMock<Templatemyclass<MockTest> > obj2;
  EXPECT_CALL(obj2.T, display())
      .Times(1)
      .WillOnce(Invoke(my_display));
  obj2.show();

  return 0;
}

I'd like that when show_text is called, it's going to call display. I try to mock display and re-route it to my_display, but that's failed. I got the error.

../test_program.cpp:56: Failure
Actual function call count doesn't match EXPECT_CALL(obj2.T, display())...
         Expected: to be called once
           Actual: never called - unsatisfied and active

Changing the above source code a bit. It can work, but this missed my expectation. I'd like to mock display that called in show_text.

template <class myclass> class Templatemyclass {
 public:
  myclass T;
  void show() ;
};

template <class myclass> void Templatemyclass<myclass>::show()
{
    T.display();
}

struct Test {

  void display()  { std::cout << __func__<<":-->Inside the display Test\n"; }

//  void show_text()  {
//    display(); // HOW to re-route it to my_display() ? (>.<)
//  }
};

struct MockTest {
  MOCK_CONST_METHOD0(display, void());
  MOCK_CONST_METHOD0(show_text, void());
};

void my_display(){
    { std::cout <<__func__<<":-->Outside the display Test\n"; }
}

int main() {
  NiceMock<Templatemyclass<Test> > obj1;
  obj1.show();

  NiceMock<Templatemyclass<MockTest> > obj2;
  EXPECT_CALL(obj2.T, display())
      .Times(1)
      .WillOnce(Invoke(my_display));
  obj2.show();

  return 0;
}

And the screen shows:

display:-->Inside the display Test
my_display:-->Outside the display Test

Please help me clear this problem.

273K
  • 29,503
  • 10
  • 41
  • 64
Thảo M. Hoàng
  • 1,224
  • 3
  • 20
  • 42

1 Answers1

1

You can't use EXPECT_CALL out of a TEST or TEST_F macro. Your main function should invoke the runner and you should place the code you now have in main within a TEST. Check the docs.

Antonio Pérez
  • 6,702
  • 4
  • 36
  • 61
  • I think that is possible because my source is running well. When I change it a bit as your said. I still run into this problem. – Thảo M. Hoàng Apr 07 '16 at 15:16
  • You can, and you get the code run, but you need the runner, among other reasons, to get the right output, command line options working and return code properly set (0 when all tests run successfully, 1 otherwise). – Antonio Pérez Apr 07 '16 at 15:39