Перемешивание с использованием boost :: shared_ptr и AMOP - PullRequest
2 голосов
/ 28 октября 2009

Я пытаюсь написать макеты, используя 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();

Это работает! Пока все хорошо, но что мне действительно нужно, так это boost :: shared_ptr в методе execute (), поэтому я пишу так:

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

Но это не работает, каким-то образом он входит в бесконечный цикл, прежде чем у меня возникла проблема с boost, когда я не нашел деструктор для смоделированного объекта, когда shared_ptr пытался удалить объект.

Кто-нибудь успешно использовал amop с boost :: shared_ptr?

Ответы [ 5 ]

0 голосов
/ 03 ноября 2013

Есть способ использовать 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();
}
0 голосов
/ 18 мая 2010

Отказ от ответственности: я автор HippoMocks

Используя HippoMocks, вы можете указать, что вы ожидаете, что деструктор будет вызван в конце вашего теста. Это также неявно подтверждает ваши ожидания в конце вашего теста. Таким образом, он может даже защитить от паразитного shared_ptr в куче, которую вы забыли удалить, или класса, который не становится владельцем или не забывает удалить указатель в случае, если вы не используете shared_ptr.

0 голосов
/ 28 октября 2009

Ну, я никогда не использовал amop, но, возможно, эта схема повышения поможет ..

Для создания буста shared_ptr вы также можете использовать

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

Таким образом, фиктивный объект не создается в стеке и уничтожается только в том случае, если счетчик ссылок в shared_ptr достигает нуля. Поскольку это по сути то же самое, что и вторая попытка, другой совет:

Если вы сталкиваетесь с проблемами, которые выглядят так, будто c ++ не находит нужного деструктора, вы можете ввести виртуальный деструктор в базовый класс (интерфейс). Позволяет ли это Amop?

class Interface{
  virtual ~Interface() { }
  ...
};
0 голосов
/ 12 февраля 2010

Вы можете назначить 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);
0 голосов
/ 28 октября 2009

Вы можете попробовать использовать более явный приведение. Я не уверен, что это сработает, но попробуйте.

// 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...