Include examples in CI tests

Also fix and update examples and documentation where required
This allows to make sure examples are actually runnable avoiding them to
become outdated
This commit is contained in:
Alexander Grund 2020-07-11 14:01:18 +02:00
parent a6aa140148
commit 5ef17d0e33
No known key found for this signature in database
GPG key ID: AA48A0760367A42B
42 changed files with 400 additions and 285 deletions

View file

@ -9,15 +9,16 @@
#ifndef CALCULATOR
#define CALCULATOR
class view;
#include "view.hpp"
//[ calculator
class calculator
{
view& v;
public:
calculator( view& v );
calculator( view& v ): v(v){}
void add( int a, int b ); // the result will be sent to the view 'v'
void add( int a, int b ){ v.display(a + b); } // the result will be sent to the view 'v'
};
//]

View file

@ -12,6 +12,7 @@
//]
#include "calculator.hpp"
#include "mock_view.hpp"
#include <boost/test/unit_test.hpp>
//[ mock_stream_user_type
namespace user_namespace
@ -36,7 +37,7 @@ bool custom_constraint( int actual )
//]
//[ custom_constraint_free_function_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two )
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_free_function )
{
mock_view v;
calculator c( v );
@ -64,7 +65,7 @@ struct custom_constraint
//]
//[ custom_constraint_functor_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two )
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_custom_constraint )
{
mock_view v;
calculator c( v );
@ -86,8 +87,7 @@ struct near_constraint
template< typename Actual >
bool operator()( Actual actual ) const
{
return std::abs( actual - unwrap_ref( expected_ ) )
< unwrap_ref( threshold_ );
return std::abs( actual - expected_ ) < threshold_ ;
}
friend std::ostream& operator<<( std::ostream& s, const near_constraint& c )
@ -109,7 +109,7 @@ mock::constraint< near_constraint< Expected > > near( Expected expected, Expecte
namespace near_constraint_test
{
//[ near_constraint_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one )
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one_near )
{
mock_view v;
calculator c( v );
@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one )
namespace near_constraint_cref_test
{
//[ near_constraint_cref_test
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one )
BOOST_AUTO_TEST_CASE( forty_one_plus_one_is_forty_two_plus_or_minus_one_near_cref )
{
mock_view v;
calculator c( v );

View file

@ -6,14 +6,69 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <functional>
#include <string>
#include <sstream>
std::function<void()> error_handler_abort;
std::function<void(const char*, int)> error_handler_pass;
std::function<void(const std::string&, const char*, int)> error_handler_call;
std::function<void(const char* message, const std::string&, const char*, int)> error_handler_fail;
template< typename Result >
struct configurable_mock_error
{
static Result abort()
{
error_handler_abort();
return Result();
}
static void pass( const char* file, int line )
{
error_handler_pass(file, line);
}
template< typename Context >
static void call( const Context& context, const char* file, int line )
{
std::stringstream s;
s << context;
error_handler_call( s.str(), file, line );
}
template< typename Context >
static void fail( const char* message, const Context& context, const char* file = "", int line = 0 )
{
std::stringstream s;
s << context;
error_handler_fail( message, s.str(), file, line );
}
};
#define MOCK_ERROR_POLICY configurable_mock_error
#define MOCK_USE_BOOST_TEST
//[ prerequisite
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
//]
#include "calculator.hpp"
#include "mock_view.hpp"
struct Fixture
{
Fixture()
{
error_handler_abort = mock::error<void>::abort;
error_handler_pass = mock::error<void>::pass;
error_handler_call = mock::error<void>::call<std::string>;
error_handler_fail = mock::error<void>::fail<std::string>;
}
};
BOOST_FIXTURE_TEST_SUITE(GettingStarted, Fixture)
namespace phases
{
//[ phases
@ -30,7 +85,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
namespace verify_reset
{
//[ verify_reset
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_reset )
{
mock_view v;
calculator c( v );
@ -49,7 +104,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
namespace expectations
{
//[ expectations
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_expect )
{
mock_view v;
calculator c( v );
@ -63,7 +118,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
namespace sequence
{
//[ sequence
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_then_1_plus_0_is_1 )
{
mock_view v;
calculator c( v );
@ -79,7 +134,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
namespace several_sequences
{
//[ several_sequences
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( add_several_numbers_in_sequences )
{
mock_view v;
calculator c( v );
@ -112,18 +167,49 @@ MOCK_BASE_CLASS( mock_view, view )
class calculator
{
view& v;
public:
calculator( view& v );
calculator( view& v ): v(v) {}
void add( int a, int b );
void add( int a, int b ){ v.display(a + b); }
};
struct CatchFailureFixture
{
static bool aborted;
static std::string fail_msg;
static void abort()
{
aborted = true;
}
static void fail( const std::string& message, const std::string&, const char* = "", int = 0 ){
fail_msg = message;
}
CatchFailureFixture()
{
error_handler_abort = abort;
error_handler_fail = fail;
}
void assert_failure(const std::string& required_message)
{
BOOST_CHECK(aborted);
BOOST_CHECK(fail_msg.find(required_message) != std::string::npos);
}
};
bool CatchFailureFixture::aborted = false;
std::string CatchFailureFixture::fail_msg;
//[ action_test
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_FIXTURE_TEST_CASE( zero_plus_zero_is_zero_with_action, CatchFailureFixture )
{
mock_view v;
calculator c( v );
MOCK_EXPECT( v.display ).once().with( 0 ); // missing returns( true )
c.add( 0, 0 );
assert_failure("missing action");
}
//]
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -1,48 +0,0 @@
// 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_comma_in_macro_problem
template< typename T1, typename T2 >
struct my_base_class
{};
//]
}
namespace limitations_comma_in_macro_solution_1
{
//[ limitations_comma_in_macro_solution_1
typedef my_base_class< int, int > my_base_type;
MOCK_BASE_CLASS( my_mock, my_base_type )
{};
//]
}
namespace limitations_comma_in_macro_solution_2
{
//[ limitations_comma_in_macro_solution_2
template< typename T1, typename T2 >
MOCK_BASE_CLASS( my_mock, my_base_class< T1 BOOST_PP_COMMA() T2 > )
{};
//]
}
namespace limitations_comma_in_macro_solution_3
{
//[ limitations_comma_in_macro_solution_3
template< typename T1, typename T2 >
struct my_mock : my_base_class< T1, T2 >, mock::object
{};
//]
}

View file

@ -6,7 +6,6 @@
// (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>
@ -35,7 +34,7 @@ namespace limitations_const_parameter_warning_explanation
//]
}
namespace limitations_const_parameter_warning_solution
namespace
{
//[ limitations_const_parameter_warning_solution
MOCK_BASE_CLASS( mock_base, base )
@ -48,3 +47,10 @@ namespace limitations_const_parameter_warning_solution
};
//]
}
BOOST_AUTO_TEST_CASE(check_method_stub_is_called)
{
mock_base b;
MOCK_EXPECT(b.method).once().with(1);
static_cast<base*>(&b)->method(1);
}

View file

@ -6,7 +6,6 @@
// (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>

View file

@ -6,7 +6,6 @@
// (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>
@ -25,3 +24,10 @@ MOCK_BASE_CLASS( mock_base, base )
MOCK_METHOD( method, 0 )
};
//]
BOOST_AUTO_TEST_CASE(method_not_called_through_base)
{
mock_base b;
MOCK_EXPECT(b.method).never();
static_cast<base*>(&b)->method(); // Doesn't call the mocked method
}

View file

@ -6,7 +6,6 @@
// (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>
@ -15,6 +14,8 @@ namespace
//[ limitations_protected_private_method_problem
class base
{
public:
void call(){ method_1(); method_2(); }
protected:
virtual void method_1() = 0;
private:
@ -30,3 +31,11 @@ namespace
};
//]
}
BOOST_AUTO_TEST_CASE(mocked_methods_are_called)
{
mock_base b;
MOCK_EXPECT(b.method_1).once();
MOCK_EXPECT(b.method_2).once();
static_cast<base*>(&b)->call();
}

View file

@ -6,7 +6,6 @@
// (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>
@ -27,7 +26,14 @@ namespace
template< typename T >
MOCK_BASE_CLASS( mock_base, base< T > )
{
MOCK_METHOD( method, 1, void() )
MOCK_METHOD( method, 0, void() )
};
//]
}
BOOST_AUTO_TEST_CASE(call_method_from_templated_class)
{
mock_base<int> b;
MOCK_EXPECT(b.method).once();
static_cast<base<int>*>(&b)->method();
}

View file

@ -6,7 +6,6 @@
// (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>
@ -17,8 +16,7 @@ class concept
{
public:
template< typename T >
void method( T t )
{}
void method( T t );
};
template< typename T >
@ -36,6 +34,14 @@ MOCK_CLASS( mock_concept )
MOCK_METHOD( method, 1, void( const char* ), method_string )
};
//]
BOOST_AUTO_TEST_CASE(mocked_templated_methods_are_called)
{
mock_concept b;
MOCK_EXPECT(b.method_int).once().with(42);
MOCK_EXPECT(b.method_string).once().with(mock::equal(std::string("string")));
function_under_test(b);
}
}
namespace limitations_template_method_problem_2
@ -80,4 +86,12 @@ std::string mock_concept::create< std::string >()
return create_string();
}
//]
BOOST_AUTO_TEST_CASE(dispatch_methods_are_called)
{
mock_concept b;
MOCK_EXPECT(b.create_int).once().returns(int{});
MOCK_EXPECT(b.create_string).once().returns(std::string{});
function_under_test(b);
}
}

View file

@ -6,7 +6,6 @@
// (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>
@ -17,14 +16,14 @@ namespace
{
virtual ~base_class() = default;
virtual void method() throw ();
virtual void method() throw() = 0;
};
//]
//[ limitations_throw_specifier_solution
MOCK_BASE_CLASS( mock_class, base_class )
{
void method() throw ()
void method() throw() override
{
method_proxy();
}
@ -32,3 +31,10 @@ namespace
};
//]
}
BOOST_AUTO_TEST_CASE(call_method_proxy)
{
mock_class b;
MOCK_EXPECT(b.method).once();
static_cast<base_class*>(&b)->method();
}

View file

@ -6,7 +6,6 @@
// (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>
#include "calculator.hpp"
@ -22,6 +21,8 @@ public:
};
//]
int calculator::add( int a, int b ){ return a + b; }
//[ simple_zero_plus_zero_is_zero
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
{
@ -51,7 +52,7 @@ public:
//]
//[ zero_plus_zero_is_zero_without_mock_object
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_without_mock_object )
{
my_view v;
calculator c( v );
@ -65,7 +66,7 @@ BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
namespace with_mock_object
{
//[ zero_plus_zero_is_zero_with_mock_object
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero )
BOOST_AUTO_TEST_CASE( zero_plus_zero_is_zero_with_mock_object )
{
mock_view v;
calculator c( v );

View file

@ -7,7 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//[ async_call_problem
namespace
namespace mock_test
{
class base_class
{
@ -17,6 +17,7 @@ namespace
class my_class
{
base_class& b;
public:
explicit my_class( base_class& );
@ -25,14 +26,23 @@ namespace
}
//]
namespace mock_test
{
my_class::my_class( base_class& b): b(b){}
void my_class::flush()
{
static int secret_value = 7;
if(--secret_value == 0)
b.method();
}
}
//[ async_call_solution
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/thread.hpp>
#include <turtle/mock.hpp>
namespace
namespace mock_test
{
template< typename F >
void check( bool& condition, F flush, int attempts = 100, int sleep = 100 )
@ -49,25 +59,15 @@ namespace
{
MOCK_METHOD( method, 0 )
};
void set_bool(bool& b)
{
b = true;
}
}
BOOST_AUTO_TEST_CASE( method_is_called )
{
using namespace mock_test;
mock_base_class m;
my_class c( m );
bool done = false;
// when method is called it will set done to true
// Note: Boost 1.57 introduced a bug preventing usage of the lambda with clang in C++98
// See: https://svn.boost.org/trac10/ticket/10785
#if defined(BOOST_CLANG) && (BOOST_VERSION >= 105700)
MOCK_EXPECT( m.method ).once().calls( std::bind(&set_bool, done) );
#else
MOCK_EXPECT( m.method ).once().calls( boost::lambda::var( done ) = true );
#endif
check( done, std::bind( &my_class::flush, &c ) ); // just wait on done, flushing from time to time
MOCK_EXPECT( m.method ).once().calls( [&done](){ done = true; } );
check( done, [&c](){ c.flush(); } ); // just wait on done, flushing from time to time
}
//]

View file

@ -9,8 +9,6 @@
//[ invoke_functor_problem
#include <functional>
namespace
{
class base_class
{
public:
@ -18,14 +16,24 @@ namespace
};
void function( base_class& ); // the function will call 'method' with a functor to be applied
}
//]
namespace
{
int receivedValue = 0;
void setx(int newValue)
{
receivedValue = newValue;
}
}
void function( base_class& c)
{
c.method(setx);
}
//[ invoke_functor_solution
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
#include <functional>
namespace
{
@ -40,5 +48,6 @@ BOOST_AUTO_TEST_CASE( how_to_invoke_a_functor_passed_as_parameter_of_a_mock_meth
mock_class mock;
MOCK_EXPECT( mock.method ).calls( [](const auto &functor){ functor(42); } ); // whenever 'method' is called, invoke the functor with 42
function( mock );
BOOST_CHECK(receivedValue == 42);
}
//]

View file

@ -7,7 +7,6 @@
// http://www.boost.org/LICENSE_1_0.txt)
//[ quick_constraint_problem
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
#include <iostream>

View file

@ -7,7 +7,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//[ retrieve_cref_problem
namespace
namespace mock_test
{
class base_class
{
@ -17,6 +17,7 @@ namespace
class my_class
{
base_class& b;
public:
explicit my_class( base_class& );
@ -25,12 +26,22 @@ namespace
}
//]
namespace mock_test
{
my_class::my_class( base_class& b): b(b){}
void my_class::process()
{
int secret_value = 42;
b.method(secret_value);
b.method(secret_value);
}
}
//[ retrieve_cref_solution
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
namespace
namespace mock_test
{
MOCK_BASE_CLASS( mock_base_class, base_class )
{
@ -40,6 +51,7 @@ namespace
BOOST_AUTO_TEST_CASE( method_is_called_two_times_with_the_same_value )
{
using namespace mock_test;
mock_base_class mock;
my_class c( mock );
int value;

View file

@ -6,8 +6,10 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Used to make this test file pass. Define to empty to see other tests fail
#define ASSERT_VERIFY_FAIL() mock::reset()
//[ static_objects_problem
#define BOOST_AUTO_TEST_MAIN
#include <boost/test/auto_unit_test.hpp>
#include <turtle/mock.hpp>
#include <ostream>
@ -16,8 +18,7 @@ namespace
{
struct my_class
{
my_class( int i )
: i_( i )
my_class( int i ) : i_( i )
{}
int i_;
@ -28,13 +29,14 @@ namespace
return os << "my_class " << c->i_; // the 'c' pointer must be valid when logging
}
MOCK_FUNCTION( f, 1, void( my_class* ) ) // being static 'f' outlive the test case
MOCK_FUNCTION( f, 1, void( my_class* ) ) // being static 'f' outlives the test case
}
BOOST_AUTO_TEST_CASE( static_objects_problem )
{
my_class c( 42 );
MOCK_EXPECT( f ).once().with( &c ); // the set expectation will also outlive the test case and leak into other test cases using 'f'
ASSERT_VERIFY_FAIL(); // Check that mock::verify fails, but that means other test fail too
} // the 'c' instance goes out of scope and the '&c' pointer becomes dangling
//]

View file

@ -9,6 +9,19 @@
#include <turtle/mock.hpp>
#include "calculator.hpp"
#include "mock_view.hpp"
#include <boost/test/unit_test.hpp>
#include <iostream>
#include <limits>
#include <stdexcept>
// Dummy to detect if the assertion unexpectedly succeeded to test what is explained
#undef BOOST_CHECK_THROW
#define BOOST_CHECK_THROW(expr, exc) \
try { \
expr; \
} catch(const exc&) { \
std::cerr << "Exception thrown but should not"; \
}
//[ overflow_throws
BOOST_AUTO_TEST_CASE( overflow_throws )

View file

@ -6,7 +6,6 @@
// (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>
@ -374,10 +373,11 @@ MOCK_CLASS( mock_class )
namespace function_example_1
{
//[ function_example_1
MOCK_FUNCTION( f, 1, float( int ) )
MOCK_FUNCTION( f, 1, void( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_function )
{
MOCK_EXPECT(f).once().with(3);
f( 3 );
}
//]
@ -398,6 +398,7 @@ namespace functor_example_1
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_functor )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT(f).once().with(3);
f( 3 );
}
//]
@ -409,12 +410,13 @@ namespace functor_example_2
template< typename T >
struct mock_class
{
MOCK_FUNCTOR_TPL( f, void( T ) );
MOCK_FUNCTOR( f, void( T ) );
};
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_functor )
BOOST_AUTO_TEST_CASE( demonstrates_instantiating_a_mock_functor_inside_a_class )
{
mock_class< int > c;
MOCK_EXPECT(c.f).once().with(3);
c.f( 3 );
}
//]
@ -436,6 +438,9 @@ BOOST_AUTO_TEST_CASE( demonstrates_configuring_mock_objects )
MOCK_EXPECT( c.method ).once().with( 0 ).in( s ).returns( 42 );
MOCK_EXPECT( c.method2 ).never().with( "ok", mock::any );
MOCK_EXPECT( c.method2 ).at_least( 2 ).in( s ).throws( std::runtime_error( "error !" ) );
BOOST_CHECK(c.method(0) == 42);
BOOST_CHECK_THROW(c.method("notok", 1.f), std::runtime_error);
BOOST_CHECK_THROW(c.method("notok", 2.f), std::runtime_error);
}
//]
}
@ -446,13 +451,18 @@ namespace invocation_example_1
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 2, void( int, const std::string& ) )
MOCK_METHOD( method2, 1, void( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_invocations_on_a_mock_method )
{
mock_class c;
MOCK_EXPECT( c.method ).once(); // can only be called once
MOCK_EXPECT( c.method ); // can be called an unlimited number of times
MOCK_EXPECT( c.method2 ); // can be called an unlimited number of times
c.method(42, "Hello world!");
c.method2(42);
c.method2(42);
c.method2(42);
}
//]
}
@ -464,6 +474,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_functor )
{
MOCK_FUNCTOR( f, void( int, const std::string& ) );
MOCK_EXPECT( f ).once();
f(42, "Hello world!");
}
//]
}
@ -476,6 +487,7 @@ MOCK_FUNCTION( f, 1, void( int ) )
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_function )
{
MOCK_EXPECT( f ).once();
f(42);
}
//]
}
@ -485,14 +497,17 @@ namespace invocation_example_4
//[ invocation_example_4
MOCK_CLASS( mock_class )
{
MOCK_STATIC_METHOD( method, 1, void( int ) )
MOCK_STATIC_METHOD( method1, 1, void( int ) )
MOCK_STATIC_METHOD( method2, 1, void( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_setting_up_an_invocation_on_a_mock_static_method )
{
mock_class c;
MOCK_EXPECT( c.method ).once();
MOCK_EXPECT( mock_class::method ).once(); // does the same
MOCK_EXPECT( c.method1 ).once();
MOCK_EXPECT( mock_class::method2 ).once(); // does the same
c.method1(42);
c.method2(42);
}
//]
}
@ -502,14 +517,17 @@ namespace constraints_example_1
//[ constraints_example_1
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 2, void( int, const std::string& ) )
MOCK_METHOD( method1, 2, void( int, const std::string& ) )
MOCK_METHOD( method2, 2, void( int, const std::string& ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_adding_builtin_constraints )
{
mock_class c;
MOCK_EXPECT( c.method ).with( mock::equal( 3 ), mock::equal( "some string" ) );
MOCK_EXPECT( c.method ).with( 3, "some string" ); // equivalent to the previous one using short-cuts
MOCK_EXPECT( c.method1 ).with( mock::equal( 3 ), mock::equal( "some string" ) );
MOCK_EXPECT( c.method2 ).with( 3, "some string" ); // equivalent to the previous one using short-cuts
c.method1(3, "some string");
c.method2(3, "some string");
}
//]
}
@ -531,6 +549,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_a_free_functi
{
mock_class c;
MOCK_EXPECT( c.method ).with( &custom_constraint );
c.method(42);
}
//]
}
@ -552,6 +571,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_a_standard_li
{
mock_class c;
MOCK_EXPECT( c.method ).with( std::bind1st( std::ptr_fun( &custom_constraint ), 42 ) ); // std::ptr_fun creates an std::unary_function
c.method(42);
}
//]
}
@ -569,10 +589,12 @@ bool custom_constraint( int expected, int actual )
return expected == actual;
}
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_boost_bind )
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_std_bind )
{
mock_class c;
using namespace std::placeholders;
MOCK_EXPECT( c.method ).with( std::bind( &custom_constraint, 42, _1 ) );
c.method(42);
}
//]
}
@ -593,6 +615,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_boost_lambda
{
mock_class c;
MOCK_EXPECT( c.method ).with( boost::lambda::_1 == 42 );
c.method(42);
}
//]
}
@ -606,14 +629,17 @@ namespace constraints_example_6
//[ constraints_example_6
MOCK_CLASS( mock_class )
{
MOCK_METHOD( method, 1, void( int ) )
MOCK_METHOD( method1, 1, void( int ) )
MOCK_METHOD( method2, 1, void( int ) )
};
BOOST_AUTO_TEST_CASE( demonstrates_adding_a_custom_constraint_with_boost_phoenix )
{
mock_class c;
MOCK_EXPECT( c.method ).with( boost::phoenix::arg_names::arg1 == 42 );
MOCK_EXPECT( c.method ).with( boost::phoenix::arg_names::_1 == 42 );
MOCK_EXPECT( c.method1 ).with( boost::phoenix::arg_names::arg1 == 42 );
MOCK_EXPECT( c.method2 ).with( boost::phoenix::arg_names::_1 == 42 );
c.method1(42);
c.method2(42);
}
//]
}
@ -630,6 +656,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_adding_a_constraint_with_cxx11_lambda )
{
mock_class c;
MOCK_EXPECT( c.method ).with( []( int actual ) { return 42 == actual; } );
c.method(42);
}
//]
}
@ -646,6 +673,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_combining_constraints )
{
mock_class c;
MOCK_EXPECT( c.method ).with( mock::less( 4 ) && mock::greater( 2 ), ! mock::equal( "" ) );
c.method(3, "Hello World!");
}
//]
}
@ -667,6 +695,7 @@ BOOST_AUTO_TEST_CASE( demonstrates_one_constraint_for_all_arguments )
{
mock_class c;
MOCK_EXPECT( c.method ).with( &custom_constraint );
c.method("1234", 4);
}
//]
}
@ -698,6 +727,9 @@ BOOST_AUTO_TEST_CASE( demonstrates_enforcing_several_expectation_orders )
MOCK_EXPECT( c_1.method_1 ).in( s_1 );
MOCK_EXPECT( c_2.method_2 ).in( s_2 ); // c_1.method_1 and c_2.method_2 are in different sequences and can be called in any order
MOCK_EXPECT( c_3.method_3 ).in( s_1, s_2 ); // c_3.method_3 must be called after both c_1.method_1 and c_2.method_2
c_2.method_2();
c_1.method_1();
c_3.method_3();
}
//]
}
@ -718,12 +750,18 @@ int function( int i )
BOOST_AUTO_TEST_CASE( demonstrates_configuring_actions )
{
mock_class c;
MOCK_EXPECT( c.method ).returns( 42 );
MOCK_EXPECT( c.method ).moves( 42 ); // returns by moving the value
MOCK_EXPECT( c.method ).throws( std::runtime_error( "error !" ) );
MOCK_EXPECT( c.method ).calls( &function ); // forwards 'method' parameter to 'function'
MOCK_EXPECT( c.method ).calls( std::bind( &function, 42 ) ); // drops 'method' parameter and binds 42 as parameter to 'function'
MOCK_EXPECT( c.method ).calls( []( int i ) { return i; } ); // uses a C++11 lambda
MOCK_EXPECT( c.method ).once().returns( 42 );
MOCK_EXPECT( c.method ).once().moves( 42 ); // returns by moving the value
MOCK_EXPECT( c.method ).once().throws( std::runtime_error( "error !" ) );
MOCK_EXPECT( c.method ).once().calls( &function ); // forwards 'method' parameter to 'function'
MOCK_EXPECT( c.method ).once().calls( std::bind( &function, 42 ) ); // drops 'method' parameter and binds 42 as parameter to 'function'
MOCK_EXPECT( c.method ).once().calls( []( int i ) { return i; } ); // uses a C++11 lambda
BOOST_CHECK(c.method(0) == 42);
BOOST_CHECK(c.method(1) == 42);
BOOST_CHECK_THROW(c.method(0), std::runtime_error);
BOOST_CHECK(c.method(2) == 2);
BOOST_CHECK(c.method(3) == 42);
BOOST_CHECK(c.method(4) == 4);
}
//]
}
@ -913,46 +951,3 @@ BOOST_AUTO_TEST_CASE( mock_constraint_2_arity )
}
//]
}
namespace helpers_example_4
{
//[ helpers_example_4
MOCK_CONSTRAINT_EXT( any, 0,, true ) // this is (almost) how mock::any is defined
MOCK_CONSTRAINT_EXT( forty_two, 0,, actual == 42 ) // this defines a 'forty_two' constraint
BOOST_AUTO_TEST_CASE( mock_constraint_0_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( forty_two );
MOCK_EXPECT( f ).with( any );
}
//]
}
namespace helpers_example_5
{
//[ helpers_example_5
MOCK_CONSTRAINT_EXT( equal, 1, ( expected ), actual == expected ) // this is how mock::equal is defined
MOCK_CONSTRAINT_EXT( near, 1, ( expected ), std::abs( actual - expected ) < 0.01 ) // this defines a 'near' constraint which can be used as 'near( 42 )'
BOOST_AUTO_TEST_CASE( mock_constraint_1_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( near( 42 ) );
MOCK_EXPECT( f ).with( equal( 42 ) );
}
//]
}
namespace helpers_example_6
{
//[ helpers_example_6
MOCK_CONSTRAINT_EXT( near, 2, ( expected, tolerance ), std::abs( actual - expected ) < tolerance ) // this is how mock::near is defined
BOOST_AUTO_TEST_CASE( mock_constraint_2_arity )
{
MOCK_FUNCTOR( f, void( int ) );
MOCK_EXPECT( f ).with( near( 42, 0.001 ) );
}
//]
}