Search code examples
c++googletest

How to set expectation on the function calls inside the constructor?


I am using google test(gtest/gmock) to add a couple of tests for the program(C++). For one of the class, I have to add a test to make sure the class is calling a function(let's say an important function I don't want to miss) in its constructor.

For example:

class foo
{
    foo()
    {
        bar();
    }
};

Here, I need to add a test to make sure bar() is called in the foo instantiation. As the expectation should be added before the action, I am finding it difficult to add such test:

For example:

foo f; // here the bar is called, so we need to set expectation before it but we got the object at this moment only

I want to use EXPECT_CALL() for this task. I am new to google test. Let me know if I am thinking clearly and what needs to be done here?

Update: bar() is an inherited member function of the foo class. I need the test to never miss that call in the further changes. That test will make sure the call is always present even after several new modifications of the source code.


Solution

  • Usually you test a class (which is not mocked) and mock the collaborators of that class (i.e. the classes that interact with it). The class being tested should not be mocked at the same time.

    In your use case, however, it looks like you are trying to test a class AND mock the same class (or the parent class) at the same time. I don't think you can do this with GMock specially if you want to test if something is called in the constructor because EXPECT_CALL requires an object of the mocked class, and by the time you create that object, the constructor is called and finished. So, you need to make a clear distinction between the class-under-test and the collaborator classes that are mocked.

    Interestingly if you try to do this here you will get a warning for an uninteresting call to bar, which is a sign that bar was called, but it's not that useful because while you get the warning, your test will fail.

    Instead, rather than using mocks and EXPECT_CALL, I suggest you create and test a side effect of bar(). To do this, you will have to slightly modify your class definitions. For example, you can write:

    class base {
       void bar(){
          //...
          bar_was_called = true;
       }
     public:
       bool bar_was_called=false;
    };
    
    class foo : public base
    {
      public:
        foo()
        {
            bar();
        }
    };
    
    TEST(foo, barWasCalled){
      foo f;
      EXPECT_TRUE(f.bar_was_called);
    }