2009-10-27 3 views
2

Я пытаюсь написать mocks с помощью amop. Я использую Visual Studio 2008.Mocking using boost :: shared_ptr и AMOP

У меня есть этот интерфейс класса:

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

Он работает! До сих пор так хорошо, но то, что я действительно хочу, это повышение :: 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(); 

собирает, но, очевидно, выходит из строя, так как в конце области переменной «насмехаться» получает двойной уничтоженную (из-за переменную стеку «издеваться» и 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(); 

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

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

ответ

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

Я попытался это, есть две проблемы: 1 подталкивание :: dynamic_pointer_cast является неудачная (всегда возвращает 0). 2- изменение кода следующим образом: amop :: TMockObject * mock = new amop :: TMockObject ; // Получить посмеянный интерфейс boost :: shared_ptr imock ((Interface *) * mock); Почти работает, но AMOP теперь не может найти методы, поэтому макет не работает. Я уверен, что amop не работает с shared_pointers (или они теряют ссылку, что-то вроде этого). –

0

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

Чтобы создать повышающий shared_ptr Вы можете также использовать

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

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

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

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

Вы можете дать 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

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

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

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(); 
} 
Смежные вопросы