Documented limitation concerning MOCK_METHOD_TPL

This commit is contained in:
Mathieu Champlon 2015-04-07 07:39:52 +02:00
parent 712653eb99
commit 12a252a850
5 changed files with 142 additions and 16 deletions

View file

@ -13,6 +13,7 @@ Not yet released
* Dropped support for obsolete Boost.Phoenix V2
* Added support for multiple parameters constraints
* Added inline to generated MOCK_FUNCTION
* Documented limitation concerning MOCK_METHOD_TPL
[section 1.2.6]
Released 24 May 2014

View 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();
}
//]
}

View file

@ -53,6 +53,22 @@ or with C++11 nullptr support :
[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]
Given :
@ -75,23 +91,27 @@ While still somewhat possible, mocking a template method can indeed prove a bit
[endsect]
[section Non-virtual methods cannot be mocked]
[section Template base class methods cannot be mocked without specifying the signature]
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]
[section Private virtual methods cannot be mocked without spelling out the signature]
[section Private virtual methods cannot be mocked without specifying the signature]
Given :
@ -101,7 +121,7 @@ the following code does not compile :
MOCK_BASE_CLASS( mock_base, base )
{
MOCK_METHOD( method, 0 ) // this fails because 'method' is not visible
MOCK_METHOD( method, 0 ) // this fails because 'method' is not visible
};
A workaround would be to add the signature to MOCK_METHOD :
@ -120,7 +140,7 @@ the following code does not compile :
MOCK_BASE_CLASS( mock_class, base_class )
{
MOCK_METHOD( method, 0 ) // this fails because of the throw specifier
MOCK_METHOD( method, 0 ) // this fails because of the throw specifier
};
A workaround would be to write a proxy member function :

View file

@ -87,18 +87,20 @@ Deriving from mock::object is optional but provides the additional following ben
Synopsis :
MOCK_METHOD( [calling convention] name, arity[, signature[, identifier]] ) // generates both const and non-const methods
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_METHOD( [calling convention] name, arity[, signature[, identifier]] ) // generates both const and non-const methods
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_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_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_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_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 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 [link turtle.reference.creation.constructor Constructors], [link turtle.reference.creation.destructor destructors] and [link turtle.reference.creation.conversion_operator conversion operators] require special care.]