【问题标题】:Mocking pure virtual methods if class also has non-virtual methods?如果类也有非虚拟方法,则模拟纯虚拟方法?
【发布时间】:2011-05-28 10:20:49
【问题描述】:

我目前正在使用 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 一起工作?还是使用其他框架?还是进行一些源代码修改?

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 我读了几次你的回答,但没明白你的意思;]你能提供一些小示例代码吗?
    【解决方案2】:

    更新/回答:我找到了一种解决方法,方法是从 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();
    

    【讨论】:

    • 如果您对 C++0x 解决方案满意,您应该将该标签添加到您的问题中。
    • done.. 可以用“标准”c++ 来完成,但打字要多得多;P
    猜你喜欢
    • 1970-01-01
    • 2012-07-29
    • 2013-05-01
    • 2015-06-13
    • 2013-10-23
    • 2011-09-30
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    相关资源
    最近更新 更多