mirror of
https://github.com/mat007/turtle.git
synced 2026-06-22 12:13:43 +00:00
Documented limitation concerning MOCK_METHOD_TPL
This commit is contained in:
parent
712653eb99
commit
12a252a850
5 changed files with 142 additions and 16 deletions
|
|
@ -13,6 +13,7 @@ Not yet released
|
||||||
* Dropped support for obsolete Boost.Phoenix V2
|
* Dropped support for obsolete Boost.Phoenix V2
|
||||||
* Added support for multiple parameters constraints
|
* Added support for multiple parameters constraints
|
||||||
* Added inline to generated MOCK_FUNCTION
|
* Added inline to generated MOCK_FUNCTION
|
||||||
|
* Documented limitation concerning MOCK_METHOD_TPL
|
||||||
|
|
||||||
[section 1.2.6]
|
[section 1.2.6]
|
||||||
Released 24 May 2014
|
Released 24 May 2014
|
||||||
|
|
|
||||||
78
doc/example/limitations_template_base_class_method.cpp
Normal file
78
doc/example/limitations_template_base_class_method.cpp
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
// http://turtle.sourceforge.net
|
||||||
|
//
|
||||||
|
// Copyright Mathieu Champlon 2014
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0.
|
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
|
||||||
|
#define BOOST_AUTO_TEST_MAIN
|
||||||
|
#include <boost/test/auto_unit_test.hpp>
|
||||||
|
#include <turtle/mock.hpp>
|
||||||
|
|
||||||
|
namespace limitations_template_base_class_method_problem
|
||||||
|
{
|
||||||
|
//[ limitations_template_base_class_method_problem
|
||||||
|
template< typename T >
|
||||||
|
class base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~base()
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void method() = 0;
|
||||||
|
};
|
||||||
|
//]
|
||||||
|
|
||||||
|
//[ limitations_template_base_class_method_solution
|
||||||
|
template< typename T >
|
||||||
|
MOCK_BASE_CLASS( mock_base, base< T > )
|
||||||
|
{
|
||||||
|
MOCK_METHOD( method, 1, void() )
|
||||||
|
};
|
||||||
|
//]
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace limitations_template_base_class_method_problem_2
|
||||||
|
{
|
||||||
|
//[ limitations_template_base_class_method_problem_2
|
||||||
|
class concept
|
||||||
|
{
|
||||||
|
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 >();
|
||||||
|
}
|
||||||
|
//]
|
||||||
|
|
||||||
|
//[ limitations_template_base_class_method_solution_2
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
//]
|
||||||
|
}
|
||||||
|
|
@ -53,6 +53,22 @@ or with C++11 nullptr support :
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
|
[section Non-virtual methods cannot be mocked]
|
||||||
|
|
||||||
|
Given :
|
||||||
|
|
||||||
|
[limitations_non_virtual_method_problem]
|
||||||
|
|
||||||
|
the following code compiles but will not work as expected :
|
||||||
|
|
||||||
|
[limitations_non_virtual_method_problem_2]
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
[section Template methods cannot be mocked]
|
[section Template methods cannot be mocked]
|
||||||
|
|
||||||
Given :
|
Given :
|
||||||
|
|
@ -75,23 +91,27 @@ While still somewhat possible, mocking a template method can indeed prove a bit
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section Non-virtual methods cannot be mocked]
|
[section Template base class methods cannot be mocked without specifying the signature]
|
||||||
|
|
||||||
Given :
|
Given :
|
||||||
|
|
||||||
[limitations_non_virtual_method_problem]
|
[limitations_template_base_class_method_problem]
|
||||||
|
|
||||||
the following code compiles but will not work as expected :
|
the following code does not compile :
|
||||||
|
|
||||||
[limitations_non_virtual_method_problem_2]
|
template< typename T >
|
||||||
|
MOCK_BASE_CLASS( mock_base, base< T > )
|
||||||
|
{
|
||||||
|
MOCK_METHOD( method, 0 ) // this fails
|
||||||
|
};
|
||||||
|
|
||||||
The mock object will never be exercised because the library relies on polymorphism to hook the calls.
|
A workaround would be to add the signature to MOCK_METHOD :
|
||||||
|
|
||||||
There is no other solution than to refactor the production code, the most simple being to change the method to virtual.
|
[limitations_template_base_class_method_solution]
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
|
||||||
[section Private virtual methods cannot be mocked without spelling out the signature]
|
[section Private virtual methods cannot be mocked without specifying the signature]
|
||||||
|
|
||||||
Given :
|
Given :
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,14 +91,16 @@ Synopsis :
|
||||||
MOCK_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] ) // generates only the const version of the method
|
MOCK_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] ) // generates only the const version of the method
|
||||||
MOCK_NON_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] ) // generates only the non-const version of the method
|
MOCK_NON_CONST_METHOD( [calling convention] name, arity[, signature[, identifier]] ) // generates only the non-const version of the method
|
||||||
|
|
||||||
MOCK_METHOD_TPL( [calling convention] name, arity[, signature[, identifier]] ) // must be used if the signature uses a template parameter of the class, generates both const and non-const methods
|
MOCK_METHOD_TPL( [calling convention] name, arity, signature[, identifier] ) // must be used if the signature uses a template parameter of the class, generates both const and non-const methods
|
||||||
MOCK_CONST_METHOD_TPL( [calling convention] name, arity[, signature[, identifier]] ) // must be used if the signature uses a template parameter of the class, generates only the const version of the method
|
MOCK_CONST_METHOD_TPL( [calling convention] name, arity, signature[, identifier] ) // must be used if the signature uses a template parameter of the class, generates only the const version of the method
|
||||||
MOCK_NON_CONST_METHOD_TPL( [calling convention] name, arity[, signature[, identifier]] ) // must be used if the signature uses a template parameter of the class, generates only the non-const version of the method
|
MOCK_NON_CONST_METHOD_TPL( [calling convention] name, arity, signature[, identifier] ) // must be used if the signature uses a template parameter of the class, generates only the non-const version of the method
|
||||||
|
|
||||||
[note If the identifier is omitted it will default to the method name.]
|
[note If the identifier is omitted it will default to the method name.]
|
||||||
|
|
||||||
[note If the method name is not ambiguous both the signature and the identifier can be omitted in the context of a derived MOCK_BASE_CLASS or base_type typedef.]
|
[note If the method name is not ambiguous both the signature and the identifier can be omitted in the context of a derived MOCK_BASE_CLASS or base_type typedef.]
|
||||||
|
|
||||||
|
[note The signature cannot be omitted for the _TPL familly of macros, see the related [link turtle.limitations.template_base_class_methods_cannot_be_mocked_without_specifying_the_signature limitation section].]
|
||||||
|
|
||||||
[note The signature must be surrounded with round parenthesis if the return type contains a comma.]
|
[note The signature must be surrounded with round parenthesis if the return type contains a comma.]
|
||||||
|
|
||||||
[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.]
|
[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.]
|
||||||
|
|
|
||||||
|
|
@ -378,8 +378,9 @@ namespace
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
MOCK_CLASS( variadic_tpl )
|
MOCK_BASE_CLASS( variadic_tpl, base )
|
||||||
{
|
{
|
||||||
|
MOCK_METHOD( m1, 0 )
|
||||||
MOCK_METHOD_TPL( m2, 0, T() )
|
MOCK_METHOD_TPL( m2, 0, T() )
|
||||||
MOCK_METHOD_TPL( m3, 0, T(), m3 )
|
MOCK_METHOD_TPL( m3, 0, T(), m3 )
|
||||||
MOCK_CONST_METHOD_TPL( m4, 0, T() )
|
MOCK_CONST_METHOD_TPL( m4, 0, T() )
|
||||||
|
|
@ -400,6 +401,30 @@ namespace
|
||||||
MOCK_FUNCTOR( f_variadic, std::map< int, int >() );
|
MOCK_FUNCTOR( f_variadic, std::map< int, int >() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else // MOCK_VARIADIC_MACROS
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct base
|
||||||
|
{
|
||||||
|
virtual ~base()
|
||||||
|
{}
|
||||||
|
protected:
|
||||||
|
virtual void m1() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
MOCK_BASE_CLASS( derived, base )
|
||||||
|
{
|
||||||
|
MOCK_METHOD( m1, 0 )
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
MOCK_BASE_CLASS( derived_tpl, base )
|
||||||
|
{
|
||||||
|
MOCK_METHOD( m1, 0 )
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#endif // MOCK_VARIADIC_MACROS
|
#endif // MOCK_VARIADIC_MACROS
|
||||||
|
|
||||||
#ifdef BOOST_MSVC
|
#ifdef BOOST_MSVC
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue