Unit testing, mocking and unique_ptr
c++, c++11, mocking, smart-pointers, unique-ptr
Solution
Hippomock already provides a solution to this problem. If you have an interface with a virtual destructor then all you need to do is to register an expectation for the destructor. The mock is not destroyed by a call to its destructor as it is a mock destructor, but an expectation for the call to the destructor must be set.
MockRepository mocks;
// create the mock
std::unique_ptr<IFoo> foo( mocks.Mock<IFoo>() );
// register the expectation for the destructor
mocks.ExpectCallDestructor( foo.get() );
// call to mocks destructor ok, mock not destroyed
foo.reset( nullptr );
Problem
There's a class under test which currently accepts a `unique_ptr< Interface >&&` in it's constructor, to express that it wants to take single ownership of an Interface implementation. Problems arise when wanting to test this class using a mocked `Interface` though: the mocking framework (HippoMocks) gives me only `Interface*` which I do not own, hence cannot delete. I had the same problem before when testing classes taking `const shared_ptr< Interface >&` as arguments, but fixed that by providing a custom no-op deleter: ``` template< class T > void NoDelete( T* ) { } //create a shared_ptr without effective deleter template< class T > std::shared_ptr< T > mock_shared( T* t ) { return std::shared_ptr< T >( t, NoDelete< T > ); } Interface* iface = mocks.GetMeAMock< Interface >(); DoStuffWithSharedPtrOfInterface( mock_shared< Interface >( iface ) ); ``` A similar fix for unique_ptr doesn't really work out because the deleter is a template argument: ``` template< class T > struct NoDelete { void operator ()( T* ) { } }; //oops this is totally useless since std::unique_ptr< T, NoDelete< T > > //is not quite the same type as std::unique_ptr< T > template< class T > std::unique_ptr< T, NoDelete< T > > mock_unique( T* t ) { return std::unique_ptr< T, NoDelete< T > >( t, NoDelete< T >() ); } ``` Is there a workaround for this? Or should I not be using unique_ptr here in the first place? update I gave this a go; should work but sizeof( ptr ) is now 8, hard to tell what impact that has. ``` //use CustomUniquePtr::type instead of uniqe_ptr template< class T > struct CustomUniquePtr { typedef typename std::unique_ptr< T, void (*) ( T* ) > type; } //use everywhere template< class T > CustomUniquePtr< T >::type make_unique( T* p ) { return CustomUniquePtr< T >::type( p, Delete< T > ); } //use when mocking, doe not delete p! template< class T > CustomUniquePtr< T >::type mock_unique( T* p ) { return CustomUniquePtr< T >::type( p, NoDelete< T > ); } ```