如何验证传递给模拟函数的参数的派生类型

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

我有一个基础 class 和两个派生的 class,像这样:

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

我还有一个正在模拟的接口 class(使用 Google Mock),如下所示:

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

我可以期待像这样调用模拟方法,根本不验证调用中的参数:

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

我想做的是验证给 someMethod 的参数类型,以检查它实际上被调用了一次 DerivedA* 一次和一次 DerivedB* , 而不是仅使用任何参数两次。

您可以为此编写匹配器函数。您的期望将如下所示

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

如果您定义了以下匹配器函数:

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;
}

请注意,如果它不是指针参数而是引用,dynamic_cast 将抛出一个 std::bad_cast 而不是返回 NULL,在类型不匹配的情况下(http://en.cppreference.com/w/cpp/language/dynamic_cast).

gMock 提供了一个指针匹配器,可用于将基 class 指针匹配到派生的 class 对象参数。 (https://github.com/google/googletest/blob/master/googlemock/docs/cheat_sheet.md#pointer-matchers)

using ::testing::NotNull;
using ::testing::WhenDynamicCastTo;

EXPECT_CALL(mockSomeInterfaceObj, someMethod(WhenDynamicCastTo<DerivedA*>(NotNull()))).Times(1);
EXPECT_CALL(mockSomeInterfaceObj, someMethod(WhenDynamicCastTo<DerivedB*>(NotNull()))).Times(1);