[section Limitations] This section lists the library known limitations. [section No support for unicode logging] There is no support for unicode logging mainly because Boost.Test does not support it either. [endsect] [section Litteral 0 cannot be used as null pointer in constraints] Given : class base { public: virtual void method( int i* ) = 0; }; MOCK_BASE_CLASS( mock_base, base ) { MOCK_METHOD( method, 1 ) }; The following code does not compile : mock_base m; MOCK_EXPECT( m.method ).with( mock::equal( 0 ) ); // this fails MOCK_EXPECT( m.method ).with( 0 ); // this fails too ! This is due to the fact that the library uses templates pretty heavily, and the litteral 0 is considered as an int when instantiating a template function. A workaround is : MOCK_EXPECT( m.method ).with( mock::equal< int* >( 0 ) ); // this compiles However a somewhat better solution would be : MOCK_EXPECT( m.method ).with( mock::negate ); or with C++11 nullptr support : MOCK_EXPECT( m.method ).with( nullptr ); [endsect] [section Template methods cannot be mocked] Given the following client code : class concept { public: template< typename T > void method( T t ) {} }; template< typename T > class client { public: client( T t ) // T is supposed to model the previous concept { t.method( 42 ); t.method( "string" ); } }; Writing a mock object modeling 'concept' requires to list all the possible versions of 'method' : MOCK_CLASS( mock_concept ) { MOCK_METHOD( method, 1, void( int ), method_int ) MOCK_METHOD( method, 1, void( const char* ), method_string ) }; While still somewhat possible, mocking a template method is indeed a bit cumbersome. [endsect] [section Private virtual methods cannot be mocked without spelling out the signature] The following code does not compile : class base { private: virtual void method() = 0; }; MOCK_BASE_CLASS( mock_base, base ) { MOCK_METHOD( method, 0 ) // this fails to compile because 'method' is not visible }; A workaround would be to add the signature to MOCK_METHOD : MOCK_BASE_CLASS( mock_base, base ) { MOCK_METHOD_EXT( method, 0, void() ) }; [endsect] [section Methods with a throw specifier cannot be mocked] The following code does not compile : namespace { struct base_class { virtual ~base_class() {} virtual void method() throw; }; MOCK_BASE_CLASS( mock_class, base_class ) { MOCK_METHOD( method, 0 ) // this fails to compile because of the throw specifier }; } A workaround would be to write a proxy member function : namespace { struct base_class { virtual ~base_class() {} virtual void method() throw; }; MOCK_BASE_CLASS( mock_class, base_class ) { void method() throw { method_proxy(); } MOCK_METHOD( method_proxy, 0, void(), method ) }; } [endsect] [section Compilers without support for variadic macros fail on commas in MOCK_BASE_CLASS] For compilers without support for variadic macros the following code does not compile : template< typename T1, typename T2 > struct my_base_class {}; MOCK_BASE_CLASS( my_mock, my_base_class< int, int > ) // this fails to compile because the pre-processor believes the macro to be called with 3 arguments {}; One workaround is : typedef my_base_class< int, int > my_base_type; MOCK_BASE_CLASS( my_mock, my_base_type ) {}; Of course this is not always possible, as in : template< typename T1, typename T2 > MOCK_BASE_CLASS( my_mock, my_base_type< T1, T2 > ) {}; Another workaround would make use of [@http://www.boost.org/libs/preprocessor Boost.Preprocessor] : template< typename T1, typename T2 > MOCK_BASE_CLASS( my_mock, my_base_type< T1 BOOST_PP_COMMA() T2 > ) {}; Actually BOOST_PP_COMMA implementation is quite trivial, being only : #define BOOST_PP_COMMA() , Finally another workaround would be to not use the macro at all : template< typename T1, typename T2 > struct my_mock : my_base_type< T1, T2 >, mock::object {}; Note that [@www.boost.org/libs/utility/identity_type/doc/html/index.html Boost.IdentityType] is of little help here because the type is by essence very often abstract, which doesn't work well for some compilers (e.g. gcc). [endsect] [section Warning C4505: '...' : unreferenced local function has been removed] Example : [teletype] warning C4505: 'base::[thunk]: __thiscall base::`vcall'{0,{flat}}' }'' : unreferenced local function has been removed [c++] This seems to be [@https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=324427 a random bug] with some versions of the Microsoft Visual Studio compiler. The only known workaround is to disable the warning with a pragma : #pragma warning( disable: 4505 ) [endsect] [section Warning C4301: '...': overriding virtual function only differs from '...' by const/volatile qualifier] Example : [teletype] warning C4301: '`anonymous-namespace'::base::method': overriding virtual function only differs from '`anonymous-namespace'::base::method' by const/volatile qualifier [c++] The following code produces this warning with some versions of the Microsoft Visual Studio compiler : class base { public: virtual void method( const int ) = 0; }; MOCK_BASE_CLASS( mock_base, base ) { MOCK_METHOD( method, 1 ) // this produces the warning MOCK_METHOD( method, 1, void( const int ) ) // forcing the signature will not help, this produces the warning too ! }; The problem is that the 'const' is actually not part of the function signature and therefore cannot be introspected. The first workaround would be to remove the 'const' all together. This is more sensible than it first sounds, after all the 'const' is useless in this situation, indeed : class derived : public base { public: virtual void method( const int ); }; void derived::method( int ) // this compiles, links and is valid C++ {} Otherwise another workaround would be to provide a proxy method : MOCK_BASE_CLASS( mock_base, base ) { void method( const int i ) { method_stub( i ); } MOCK_METHOD( method_stub, 1, void( int ), method ) }; [endsect] [section Warning C4267: 'argument' : conversion from 'size_t' to 'unsigned int', possible loss of data] Compiling under Microsoft Visual Studio with the /Wp64 flag produces this warning at various locations in the library code. This is actually a bug in the compiler, for more information see [@http://connect.microsoft.com/VisualStudio/feedback/details/253172/incorrect-warning-c4267 incorrect-warning-c4267]. [endsect] [section Using C++11 lambda as constraints requires decltype compiler support] The technique used in order to detect whether a constraint is a C++11 lambda or not is based on decltype, which means the library can fail to detect a lambda in case the compiler does not support it. [endsect] [endsect]