Search code examples
c++unit-testinggoogletestgooglemock

How to verify the derived type of a parameter passed to a mocked function


I have a base class and two derived classes, like this:

class Base { ... };
class DerivedA : public Base { ... };
class DerivedB : public Base { ... };

I also have an interface class which I'm mocking (with Google Mock), like this:

class MockSomeInterface : public SomeInterface
{
  public:
    MOCK_METHOD1(someMethod, void(Base* basePtr));
};

I can expect calls to the mocked method like this, not verifying the parameter in the call at all:

EXPECT_CALL(mockSomeInterfaceObj, someMethod(_))
  Times(2);

What i would like to do is verify the type of the parameter given to someMethod, to check that it is in fact called with a DerivedA* once and a DerivedB* once, instead of just twice with any parameter.


Solution

  • You can write matcher functions for this. Your expectations will then look like this

    {
      InSequence s;
      EXPECT_CALL(mockSomeInterfaceObj, someMethod(IsDerivedA()))
        Times(1);
      EXPECT_CALL(mockSomeInterfaceObj, someMethod(IsDerivedB()))
        Times(1);
    }
    

    if you have defined the following matcher functions:

    MATCHER(IsDerivedA, "")
    {
      if (arg == NULL)
      {
        return false;
      }
      DerivedA* derived = dynamic_cast<DerivedA*>(arg);
      if (derived == NULL)
      {
        *result_listener << "is NOT a DerivedA*";
        return false;
      }
      return true;
    }
    
    MATCHER(IsDerivedB, "")
    {
      if (arg == NULL)
      {
        return false;
      }
      DerivedB* derived = dynamic_cast<DerivedB*>(arg);
      if (derived == NULL)
      {
        *result_listener << "is NOT a DerivedB*";
        return false;
      }
      return true;
    }
    

    Notice though that if it's not a pointer parameter but a reference, dynamic_cast will throw an std::bad_cast instead of returning NULL, in the case of types not matching (http://en.cppreference.com/w/cpp/language/dynamic_cast).