如果类也有非虚方法,则模拟纯虚方法?

时间:2011-05-28 10:20:49

标签: c++ unit-testing mocking c++11

我目前正在使用HippoMocks作为模拟框架,并且无法弄清楚如何在下面的代码中模拟纯虚方法MockMe()。我想要模拟任何非虚拟方法(可能甚至不可能),而是我希望他们做他们想要做的事情并调用模拟的虚拟方法。

struct A
{
  void Run() { RunImpl(); }
  virtual void RunImpl() = 0;
};

struct B : public A
{
    //implement A::RunImpl
  void RunImpl() { MockMe(); }

    //this one I want to mock
  virtual void MockMe() = 0;
};

MockRepository mocks;
B* b = mocks.InterfaceMock< B >();
mocks.OnCall( b, B::MockMe );
b->Run(); //throws NotImplementedException for Run()

有没有办法让这个与HippoMocks合作?或者与另一个框架?或者进行一些源修改?

2 个答案:

答案 0 :(得分:0)

我没有使用过模拟框架,但这应该是更容易做的事情之一......

使用B类扩展Mock类,其中只覆盖纯虚方法并转发构造函数。然后实例化派生类并将其作为引用/指针传递给模拟类,这是应用程序的其余部分可能已准备好处理的事情:如果类具有纯虚函数,则应用程序通过指针以多态方式使用它和/或参考。

答案 1 :(得分:0)

更新/回答:我通过从B派生一个新类并添加一个助手来将调用转发到适当的方法,从而找到了解决方法。除此之外,使用ClassMock代替InterfaceMock也很重要。

因此,使用上面的示例,这有效:

struct MockHelper : public B
{
  void InvokeRunImpl()
  {
    B::RunImpl();
  }

  virtual void MockMe()
  {
    //never called, but must be defined so MockHelper can be instantiated
  }
};

MockHelper* b = mocks.ClassMock< MockHelper >();
auto invokeIt = [b]() { b->InvokeRunImpl(); };
mocks.OnCall( b, MockHelper::RunImpl ).Do( invokeIt );
mocks.OnCall( b, MockHelper::MockMe );
//ok now: calls A::Run, which calls mocked RunImpl, which in turn
//calls InvokeRunImpl, which in turn calls B::RunImpl
b->Run();