【问题标题】:Mocking using boost::shared_ptr and AMOP使用 boost::shared_ptr 和 AMOP 进行模拟
【发布时间】:2013-11-05 00:27:25
【问题描述】:

我正在尝试使用amop 编写模拟。我正在使用 Visual Studio 2008。

我有这个接口类:

struct Interface {
   virtual void Activate() = 0;
};

还有这个接收指向这个Interface的指针的其他类,像这样:

struct UserOfInterface {
   void execute(Interface* iface) {
      iface->Activate();
   }
};

所以我试着写一些这样的测试代码:

amop::TMockObject<Interface> mock;
mock.Method(&Interface::Activate).Count(1);

UserOfInterface user;
user.execute((Interface*)mock);

mock.Verifiy();

有效!到目前为止一切顺利,但我真正想要的是在 execute() 方法中的 boost::shared_ptr,所以我写了这个:

struct UserOfInterface {
   void execute(boost::shared_ptr<Interface> iface) {
      iface->Activate();
   }
};

测试代码现在应该如何?我尝试了一些东西,例如:

amop::TMockObject<Interface> mock;
mock.Method(&Interface::Activate).Count(1);

UserOfInterface user;
boost::shared_ptr<Interface> mockAsPtr((Interface*)mock);
user.execute(mockAsPtr);

mock.Verifiy();

它可以编译,但显然会崩溃,因为在作用域的末尾,变量 'mock' 被双重破坏(因为堆栈变量 'mock' 和 shared_ptr)。

我还尝试在堆上创建“模拟”变量:

amop::TMockObject<Interface>* mock(new amop::TMockObject<Interface>);
mock->Method(&Interface::Activate).Count(1);

UserOfInterface user;
boost::shared_ptr<Interface> mockAsPtr((Interface*)*mock);
user.execute(mockAsPtr);

mock->Verifiy();

但它不起作用,不知何故进入了一个无限循环,在我遇到 boost 在 shared_ptr 试图删除对象时找不到模拟对象的析构函数之前遇到问题。

有人成功使用amop 和 boost::shared_ptr 吗?

【问题讨论】:

    标签: c++ boost mocking


    【解决方案1】:

    您可能想尝试使用更明确的演员表。我不确定这是否可行,但请尝试一下。

    // Get the mock generator
    boost::shared_ptr< amop::TMockObject<Interface> > mock
        = boost::make_shared< amop::TMockObject<Interface> >;
    // Get the mocked interface
    boost::shared_ptr<Interface> imock = boost::dynamic_pointer_cast<Interface>(mock);
    
    // Setup mock usage expectations
    mock->Method(&Interface::Activate).Count(1);
    
    // Run the test
    UserOfInterface user;
    user.execute(imock);
    
    // Verify the expectations were met
    mock->Verifiy();
    

    【讨论】:

    • 我试过了,有两个问题: 1- boost::dynamic_pointer_cast 不成功(总是返回 0)。 2-将代码更改为: amop::TMockObject* mock= new amop::TMockObject; // 获取模拟接口 boost::shared_ptr imock((Interface*)*mock);几乎可以工作,但 AMOP 现在找不到方法,所以模拟不起作用。我很确定 amop 不能很好地与 shared_pointers 一起工作(或者他们失去了参考,类似的东西)。
    【解决方案2】:

    好吧,我从未使用过 amop,但也许这种提升模式会有所帮助..

    要创建一个 boost shared_ptr 你也可以使用

    boost::shared_ptr<Interface> mock(new amop::TMockObject<Interface>());
    

    这样,模拟对象不会在堆栈上创建,只有在 shared_ptr 中的引用计数器变为零时才会被销毁。 因为这与您的第二次尝试基本相同,所以另一个提示:

    如果您遇到的问题看起来像 c++ 没有找到正确的析构函数,您可能会在基(接口)类中引入一个虚拟析构函数。 amop 允许这样做吗?

    class Interface{
      virtual ~Interface() { }
      ...
    };
    

    【讨论】:

      【解决方案3】:

      您可以给 shared_ptr 一个自定义函子,当引用计数变为零时,它将被调用而不是删除。

      然后代码将如下所示(我没有尝试编译它):

      struct NoOpDel
      {
      void operator() (void *) { }
      }
      
      amop::TMockObject<Interface> mock;
      mock.Method(&Interface::Activate).Count(1);
      
      UserOfInterface user;
      boost::shared_ptr<Interface> imock((Interface*)mock, NoOpDel())
      user.execute(imock);
      
      mock.Verify();
      

      更多详情见Boost API doc,你对这个构造函数感兴趣:

      template<class Y, class D> shared_ptr(Y * p, D d);
      

      【讨论】:

        【解决方案4】:

        免责声明:我是 HippoMocks 的作者

        使用 HippoMocks,您可以指定您希望在测试结束时调用析构函数。它还在测试结束时隐含地验证了您的期望。这样,它甚至可以防止您忘记删除的堆上的杂散 shared_ptr 或不拥有所有权的类或在您不使用 shared_ptr 的情况下忘记删除指针。

        【讨论】:

          【解决方案5】:

          有一种方法可以将 shared_ptr 与 amop 一起使用

          struct Interface {
             virtual ~Interface() {}
             virtual void Activate() = 0;
          };
          
          TEST(MockObjectMethodDestructor)
          {  
              TMockObject<Interface> mock;
          
              mock.Method(Destructor());
          
              boost::shared_ptr<Interface> ptr((IInterface*)mock);
          
              ptr.reset();
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-06-12
            • 2013-04-16
            • 1970-01-01
            • 2013-07-09
            • 2023-04-03
            • 1970-01-01
            相关资源
            最近更新 更多