Updated documentation

git-svn-id: https://svn.code.sf.net/p/turtle/code/trunk@601 860be788-9bd5-4423-9f1e-828f051e677b
This commit is contained in:
mat007 2013-03-07 07:17:14 +00:00
parent 6491d11d19
commit b4b9d732d3
4 changed files with 109 additions and 46 deletions

View file

@ -1,5 +1,14 @@
[section Changelog]
[section trunk]
Not yet released
* Added variadic macro support for MOCK_FUNCTION and the MOCK_METHOD family
* Added variadic macro support for MOCK_BASE_CLASS and MOCK_FUNCTOR
* Added round parenthesis support for signatures for MOCK_FUNCTION, MOCK_FUNCTOR and the MOCK_METHOD family
[endsect]
[section 1.2.1]
Released 24 January 2013

View file

@ -68,15 +68,15 @@ Writing a mock object modeling 'concept' requires to list all the possible versi
MOCK_CLASS( mock_concept )
{
MOCK_METHOD_EXT( method, 1, void( int ), method_int )
MOCK_METHOD_EXT( method, 1, void( const char* ), method_string )
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 A private pure virtual method cannot be mocked using MOCK_METHOD]
[section Private virtual methods cannot be mocked without spelling out the signature]
The following code does not compile :
@ -91,18 +91,57 @@ The following code does not compile :
MOCK_METHOD( method, 0 ) // this fails to compile because 'method' is not visible
};
The workaround would be to use MOCK_METHOD_EXT :
The workaround would be to add the signature to MOCK_METHOD :
MOCK_BASE_CLASS( mock_base, base )
{
MOCK_METHOD_EXT( method, 0, void(), method )
MOCK_METHOD_EXT( method, 0, void() )
};
[endsect]
[section Commas are not allowed in templates in MOCK_BASE_CLASS]
[section Compilers without support for variadic macros cannot rely solely on MOCK_METHOD]
The following code does not compile :
MOCK_CLASS( my_mock )
{
MOCK_METHOD( method_1, 0, void() ) // this fails to compile with compilers without variadic macros
MOCK_METHOD( method_2, 0, void(), method_2 ) // this too fails with compilers without variadic macros
};
The workaround would be to use the MOCK_METHOD_EXT macro :
MOCK_CLASS( my_mock )
{
MOCK_METHOD_EXT( method_1, 0, void(), method_1 ) // the last argument must be specified
MOCK_METHOD_EXT( method_2, 0, void(), method_2 )
};
The last 'identifier' argument must also always be specified for all other macros.
Synopsis :
MOCK_METHOD_EXT( name, arity, signature, identifier ) // generates both const and non-const methods, compatible with compilers not supporting variadic macros
MOCK_CONST_METHOD_EXT( name, arity, signature, identifier ) // generates only the const version of the method, for compilers not supporting variadic macros
MOCK_NON_CONST_METHOD_EXT( name, arity, signature, identifier ) // generates only the non-const version of the method, for compilers not supporting variadic macros
MOCK_METHOD_EXT_TPL( name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class, for compilers not supporting variadic macros
MOCK_CONST_METHOD_EXT_TPL( name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class, for compilers not supporting variadic macros
MOCK_NON_CONST_METHOD_EXT_TPL( name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class, for compilers not supporting variadic macros
MOCK_STATIC_METHOD( name, arity, signature, identifier )
MOCK_STATIC_METHOD_TPL( name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class, 'identifier' cannot be omitted, for compilers not supporting variadic macros
MOCK_FUNCTION( name, arity, signature, identifier ) // 'identifier' cannot be omitted, for compilers not supporting variadic macros
The other parts of the user interface remain unchanged.
Of course those macros are also available for compilers which support variadic macros.
[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
@ -140,7 +179,7 @@ Finally another workaround would be to not use the macro at all :
struct my_mock : my_base_type< T1, T2 >, mock::object
{};
The extra features provided by MOCK_BASE_CLASS are not usable with template base classes anyway because there is no equivalent of MOCK_METHOD for them.
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]
@ -182,8 +221,8 @@ The following code produces this warning with some versions of the Microsoft Vis
MOCK_BASE_CLASS( mock_base, base )
{
MOCK_METHOD( method, 1 ) // this produces the warning
MOCK_METHOD_EXT( method, 1, void( const int ), method ) // this produces the warning too !
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.
@ -209,7 +248,7 @@ Otherwise another workaround would be to provide a proxy method :
{
method_stub( i );
}
MOCK_METHOD_EXT( method_stub, 1, void( int ), method )
MOCK_METHOD( method_stub, 1, void( int ), method )
};
[endsect]

View file

@ -48,6 +48,13 @@ Despite being often considered harmful they also provide a number of advantages
* they make the interface homogeneous (MOCK_FUNCTOR, MOCK_CLASS)
* line number and file name can be added for logging purposes (MOCK_EXPECT)
Variadic macros are available for fairly recent compilers and provide a smoother user interface :
* they help seemlessly support arguments containing commas (MOCK_BASE_CLASS)
* they make some of the parameters optional (MOCK_METHOD)
An alternate more portable set of macros is provided for maximum portability if needed.
[endsect]
[endsect]

View file

@ -139,15 +139,14 @@ Example :
Synopsis :
MOCK_METHOD( name, arity ) // only works in the context of a derived MOCK_BASE_CLASS or base_type typedef and generates both const and non-const methods
MOCK_METHOD( name, arity ) // generates both const and non-const methods, only works in the context of a derived MOCK_BASE_CLASS or base_type typedef
MOCK_METHOD( name, arity, signature[, identifier] ) // generates both const and non-const methods, if 'identifier' is omitted it will default to 'name'
MOCK_CONST_METHOD( name, arity, signature[, identifier] ) // generates only the const version of the method, if 'identifier' is omitted it will default to 'name'
MOCK_NON_CONST_METHOD( name, arity, signature[, identifier] ) // generates only the non-const version of the method, if 'identifier' is omitted it will default to 'name'
MOCK_METHOD_EXT( name, arity, signature, identifier ) // generates both const and non-const methods
MOCK_CONST_METHOD_EXT( name, arity, signature, identifier ) // generates only the const version of the method
MOCK_NON_CONST_METHOD_EXT( name, arity, signature, identifier ) // generates only the non-const version of the method
MOCK_METHOD_EXT_TPL( name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class
MOCK_CONST_METHOD_EXT_TPL( name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class
MOCK_NON_CONST_METHOD_EXT_TPL( name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class
MOCK_METHOD_TPL( name, arity, signature[, identifier] ) // must be used if the signature uses a template parameter of the class, if 'identifier' is omitted it will default to 'name'
MOCK_CONST_METHOD_TPL( name, arity, signature[, identifier] ) // must be used if the signature uses a template parameter of the class, if 'identifier' is omitted it will default to 'name'
MOCK_NON_CONST_METHOD_TPL( name, arity, signature[, identifier] ) // must be used if the signature uses a template parameter of the class, if 'identifier' is omitted it will default to 'name'
[note [link turtle.reference.creation.constructor Constructors], [link turtle.reference.creation.destructor destructors] and [link turtle.reference.creation.conversion_operator conversion operators] require special care]
@ -173,10 +172,12 @@ Example :
MOCK_BASE_CLASS( mock_class, base_class )
{
MOCK_METHOD_EXT( method, 2, void( int, const std::string& ), identifier_1 ) // MOCK_METHOD cannot be used because of overloading
MOCK_METHOD_EXT( method, 1, void( float ), identifier_2 ) // the identifier must differ from the previous one in order to fully disambiguate methods
MOCK_METHOD( method, 2, void( int, const std::string& ), identifier_1 ) // MOCK_METHOD cannot be used because of overloading
MOCK_METHOD( method, 1, void( float ), identifier_2 ) // the identifier must differ from the previous one in order to fully disambiguate methods
};
[note For a compiler not supporting variadic macros MOCK_METHOD_EXT must be used instead]
Example :
class base_class
@ -200,8 +201,8 @@ Example :
MOCK_BASE_CLASS( mock_class, base_class )
{
MOCK_CONST_METHOD_EXT( method, 1, void( float ), identifier_1 ) // this generates only the const version
MOCK_NON_CONST_METHOD_EXT( method, 1, void( float ), identifier_2 ) // this generates only the non-const version, with a different identifier
MOCK_CONST_METHOD( method, 1, void( float ), identifier_1 ) // this generates only the const version
MOCK_NON_CONST_METHOD( method, 1, void( float ), identifier_2 ) // this generates only the non-const version, with a different identifier
};
Example :
@ -222,7 +223,7 @@ Example :
MOCK_CLASS( mock_class )
{
MOCK_NON_CONST_METHOD_EXT( operator=, 1, mock_class&( const mock_class& ), assignment ) // operators need a custom identifier
MOCK_NON_CONST_METHOD( operator=, 1, mock_class&( const mock_class& ), assignment ) // operators need a custom identifier
};
Example :
@ -230,7 +231,14 @@ Example :
template< typename T >
MOCK_CLASS( mock_class )
{
MOCK_METHOD_EXT_TPL( method, 1, void( const T& ), method ) // the _TPL variants must be used if the signature includes a template parameter of the class
MOCK_METHOD_TPL( method, 1, void( const T& ) ) // the _TPL variants must be used if the signature includes a template parameter of the class
};
If 'signature' has a return type which contains a comma, for instance std::map< int, int >(), then 'signature' must be surrounded with round parenthesis, for instance :
struct mock_class
{
MOCK_METHOD( method, 0, (std::map< int, int >()) )
};
[endsect]
@ -239,14 +247,14 @@ Example :
Synopsis :
MOCK_STATIC_METHOD( name, arity, signature, identifier )
MOCK_STATIC_METHOD_TPL( name, arity, signature, identifier ) // must be used if the signature uses a template parameter of the class
MOCK_STATIC_METHOD( name, arity, signature[, identifier] ) // if 'identifier' is omitted it will default to 'name'
MOCK_STATIC_METHOD_TPL( name, arity, signature[, identifier] ) // must be used if the signature uses a template parameter of the class, if 'identifier' is omitted it will default to 'name'
Example :
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( method, 1, float( int ), method )
MOCK_STATIC_METHOD( method, 1, float( int ) )
};
[note A static object is used behind the scene in order to keep track of the expectations of a mock static method, therefore to ensure all tests run in isolation it is strongly suggested to manually [link turtle.reference.verification verify] and [link turtle.reference.reset reset] the static method at the end of each test]
@ -334,13 +342,13 @@ Example :
Synopsis :
MOCK_FUNCTION( name, arity, signature, identifier )
MOCK_FUNCTION( name, arity, signature[, identifier] ) // if 'identifier' is omitted it will default to 'name'
[note A static object is used behind the scene in order to keep track of the expectations of a mock free function, therefore to ensure all tests run in isolation it is strongly suggested to manually [link turtle.reference.verification verify] and [link turtle.reference.reset reset] the mock function at the end of each test]
Example :
MOCK_FUNCTION( mock_function, 1, float( int ), mock_function )
MOCK_FUNCTION( mock_function, 1, float( int ) )
[endsect]
@ -360,8 +368,8 @@ Example :
MOCK_CLASS( mock_class )
{
MOCK_METHOD_EXT( method, 0, int( int ), method )
MOCK_METHOD_EXT( method, 0, void( const std::string&, float ), method2 )
MOCK_METHOD( method, 0, int( int ), method )
MOCK_METHOD( method, 0, void( const std::string&, float ), method2 )
};
BOOST_AUTO_TEST_CASE( demonstrates_configuring_mock_objects )
@ -389,7 +397,7 @@ Example :
MOCK_CLASS( mock_class )
{
MOCK_METHOD_EXT( method, 2, void( int, const std::string& ), method )
MOCK_METHOD( method, 2, void( int, const std::string& ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_invocations_on_a_mock_method )
@ -409,7 +417,7 @@ Example :
Example :
MOCK_FUNCTION( free_function, 1, float( int ), free_function )
MOCK_FUNCTION( free_function, 1, float( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_function )
{
@ -420,7 +428,7 @@ Example :
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( method, 1, float( int ), method )
MOCK_STATIC_METHOD( method, 1, float( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_static_method )
@ -483,7 +491,7 @@ Example :
MOCK_CLASS( mock_class )
{
MOCK_METHOD_EXT( method, 2, void( int, const std::string& ), method )
MOCK_METHOD( method, 2, void( int, const std::string& ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_adding_builtin_constraints )
@ -571,11 +579,11 @@ Example :
MOCK_CLASS( mock_class_1 )
{
MOCK_METHOD_EXT( method_1, 0, void(), method_1 )
MOCK_METHOD( method_1, 0, void() )
};
MOCK_CLASS( mock_class_2 )
{
MOCK_METHOD_EXT( method_2, 0, void(), method_2 )
MOCK_METHOD( method_2, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_enforcing_expectations_order )
@ -591,7 +599,7 @@ Example of setting several sequences by chaining calls to ['in] :
MOCK_CLASS( mock_class )
{
MOCK_METHOD_EXT( method, 0, void(), method )
MOCK_METHOD( method, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_enforcing_several_expectations_orders )
@ -615,7 +623,7 @@ Example :
MOCK_CLASS( mock_class )
{
MOCK_METHOD_EXT( method, 0, int( int ), method )
MOCK_METHOD( method, 0, int( int ) )
};
int function( int i )
@ -655,7 +663,7 @@ Example :
MOCK_CLASS( mock_class )
{
MOCK_METHOD_EXT( method, 0, void(), method )
MOCK_METHOD( method, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_verifying_a_mock_method )
@ -678,7 +686,7 @@ Example :
Example :
MOCK_FUNCTION( f, 1, void( int ), f )
MOCK_FUNCTION( f, 1, void( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_verifying_a_mock_function )
{
@ -690,7 +698,7 @@ Example :
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( method, 0, void(), method )
MOCK_STATIC_METHOD( method, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_verifying_a_static_mock_method )
@ -714,7 +722,7 @@ Example :
MOCK_CLASS( mock_class )
{
MOCK_METHOD_EXT( method, 0, void(), method )
MOCK_METHOD( method, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_resetting_a_mock_method )
@ -736,7 +744,7 @@ Example :
Example :
MOCK_FUNCTION( f, 1, void( int ), f )
MOCK_FUNCTION( f, 1, void( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_resetting_a_mock_function )
{
@ -748,7 +756,7 @@ Example :
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( method, 0, void(), method )
MOCK_STATIC_METHOD( method, 0, void() )
};
BOOST_AUTO_TEST_CASE( demonstrates_resetting_a_static_mock_method )