使用boost :: shared_ptr和AMOP进行模拟

时间:2009-10-27 21:13:45

标签: c++ boost mocking

我正在尝试使用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)。

我还尝试在堆上创建'mock'变量:

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

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

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

5 个答案:

答案 0 :(得分:0)

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

// 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 :(得分:0)

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

要创建boost shared_ptr,您还可以使用

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

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

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

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

答案 2 :(得分:0)

您可以为shared_ptr提供一个自定义函子,当引用计数变为零时,将调用该函数而不是delete。

然后代码看起来像这样(我没有尝试编译它):

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

答案 3 :(得分:0)

免责声明:我是HippoMocks的作者

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

答案 4 :(得分:0)

有一种方法可以将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();
}