开发者

Mocking pure virtual methods if class also has non-virtual methods?

I am currently using HippoMocks as mocking framework, and can't figure out how to mock the pure virtual method MockMe() in the code below. I do not want to mock any of the non-virtual methods (which is likely not even possible), instead I want them to do what they are meant for and call the mocked virtual one.

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.开发者_Go百科InterfaceMock< B >();
mocks.OnCall( b, B::MockMe );
b->Run(); //throws NotImplementedException for Run()

Is there any way to get this working with HippoMocks? Or with another framework? Or with some source modifications?


I haven't used mocking frameworks, but this should be one of the easier things to do...

Extend the B class with a Mock class, where you only override the pure virtual methods and forward on the constructors. Then instantiate the derived class and pass it as a reference/pointer to the mocked class, which is something the rest of the application is probably ready to handle: if the class has pure virtual functions, then the application is using it polymorphically, through pointers and/or references.


update/answer: I found a way around it by deriving a new class from B and adding a helper to forward the calls to the appropriate method. Apart from that it's also important to use ClassMock instead of InterfaceMock.

So, using the example above, this works:

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();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜