Download | News | Support | Project |
This section lists the library known limitations.
There is no support for unicode logging mainly because Boost.Test does not support it either.
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 :
BOOST_AUTO_TEST_CASE( literal_zero ) { 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 literal 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);
Given :
class base { public: void method() // the method is not virtual {} };
the following code compiles but will not work as expected :
MOCK_BASE_CLASS(mock_base, base) { MOCK_METHOD(method, 0) };
The mock object will never be exercised because the library relies on polymorphism to hook the calls.
There is no other solution than to refactor the production code, the most simple being to change the method to virtual.
Given :
class concept_class { public: template<typename T> void method(T t); }; template<typename T> void function_under_test(T t) // T is supposed to model the previous concept { t.method(42); t.method("string"); }
writing a mock object modeling the 'concept class' 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) };
However if one or more template parameters must be explicitly specified as in :
class concept_class { public: template<typename T> T create() { return T(); } }; template<typename T> void function_under_test(T t) // T is supposed to model the previous concept { t.template create<int>(); t.template create<std::string>(); }
delegate methods must be manually added :
MOCK_CLASS(mock_concept) { template<typename T> T create(); MOCK_METHOD(create_int, 0, int(), create_int) MOCK_METHOD(create_string, 0, std::string(), create_string) }; template<> int mock_concept::create<int>() { return create_int(); } template<> std::string mock_concept::create<std::string>() { return create_string(); }
While still somewhat possible, mocking a template method can indeed prove a bit cumbersome.
Given :
template<typename T> class base { public: virtual ~base() = default; virtual void method() = 0; };
the following code does not compile :
template< typename T > MOCK_BASE_CLASS( mock_base, base< T > ) { MOCK_METHOD( method, 0 ) // this fails };
A workaround would be to add the signature to MOCK_METHOD :
template<typename T> MOCK_BASE_CLASS(mock_base, base<T>) { MOCK_METHOD(method, 0, void()) };
Given :
class base { public: void call() { method_1(); method_2(); } protected: virtual void method_1() = 0; private: virtual void method_2() = 0; };
the following code does not compile :
MOCK_BASE_CLASS( mock_base, base ) { MOCK_METHOD( method_1, 0 ) // this fails because a function pointer on 'base::method_1' is not allowed MOCK_METHOD( method_2, 0 ) // this fails because 'method_2' is not visible };
A workaround would be to add the signature to MOCK_METHOD :
MOCK_BASE_CLASS(mock_base, base) { MOCK_METHOD(method_1, 0, void()) MOCK_METHOD(method_2, 0, void()) };
Given :
struct base_class { virtual ~base_class() = default; virtual void method() throw() = 0; };
the following code does not compile :
MOCK_BASE_CLASS( mock_class, base_class ) { MOCK_METHOD( method, 0 ) // this fails because of the throw specifier };
A workaround would be to write a proxy member function :
MOCK_BASE_CLASS(mock_class, base_class) { void method() throw() override { method_proxy(); } MOCK_METHOD(method_proxy, 0, void(), method) };
Example :
warning C4505: 'base::[thunk]: __thiscall base::`vcall'{0,{flat}}' }'' : unreferenced local function has been removed
This seems to be 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 )
Example :
warning C4301: '`anonymous-namespace'::base::method': overriding virtual function only differs from '`anonymous-namespace'::base::method' by const/volatile qualifier
Given :
class base { public: virtual void method(const int) = 0; };
the following code produces this warning with some versions of the Microsoft Visual Studio compiler :
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 the following compiles, links and is valid C++ :
class derived : public base { public: virtual void method(const int); }; void derived::method(int) {}
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) };
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 incorrect-warning-c4267.
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.