diff --git a/src/libraries/turtle/function.hpp b/src/libraries/turtle/function.hpp index 1fee2bc..4318381 100644 --- a/src/libraries/turtle/function.hpp +++ b/src/libraries/turtle/function.hpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -139,7 +140,7 @@ namespace mock } private: - class function_impl : public detail::verifiable + class function_impl : public detail::verifiable, public boost::enable_shared_from_this< function_impl > { public: typedef MOCK_ERROR_POLICY< result_type > error_type; @@ -191,6 +192,7 @@ namespace mock virtual void reset() { valid_ = true; + boost::shared_ptr< function_impl > guard = shared_from_this(); expectations_.clear(); } diff --git a/src/libraries/turtle/group.hpp b/src/libraries/turtle/group.hpp index db28940..e60417d 100644 --- a/src/libraries/turtle/group.hpp +++ b/src/libraries/turtle/group.hpp @@ -42,10 +42,14 @@ namespace detail valid = false; return valid; } - void reset() const + void reset() { - std::for_each( verifiables_.begin(), verifiables_.end(), - std::mem_fun( &verifiable::reset ) ); + const verifiables_t verifiables = verifiables_; + for( verifiables_cit it = verifiables.begin(); + it != verifiables.end(); ++it ) + if( std::find( verifiables_.begin(), verifiables_.end(), *it ) + != verifiables_.end() ) + (*it)->reset(); } private: diff --git a/src/libraries/turtle/object.hpp b/src/libraries/turtle/object.hpp index 6de3ec5..c66af8c 100644 --- a/src/libraries/turtle/object.hpp +++ b/src/libraries/turtle/object.hpp @@ -15,6 +15,7 @@ #include "parent.hpp" #include "child.hpp" #include "type_name.hpp" +#include #include #include #include @@ -33,7 +34,7 @@ namespace mock {} private: - class object_impl : public detail::context, private detail::verifiable + class object_impl : public detail::context, public detail::verifiable, public boost::enable_shared_from_this< object_impl > { public: virtual void add( const void* /*p*/, detail::verifiable& v, @@ -73,6 +74,7 @@ namespace mock } virtual void reset() { + boost::shared_ptr< object_impl > guard = shared_from_this(); group_.reset(); } diff --git a/src/libraries/turtle/root.hpp b/src/libraries/turtle/root.hpp index f70b8ee..10e119d 100644 --- a/src/libraries/turtle/root.hpp +++ b/src/libraries/turtle/root.hpp @@ -54,7 +54,7 @@ namespace detail { return group_.verify(); } - void reset() const + void reset() { group_.reset(); } diff --git a/src/tests/turtle_test/integration_test.cpp b/src/tests/turtle_test/integration_test.cpp index 6abd303..32c3ff3 100644 --- a/src/tests/turtle_test/integration_test.cpp +++ b/src/tests/turtle_test/integration_test.cpp @@ -535,3 +535,39 @@ BOOST_AUTO_TEST_CASE( a_static_method_in_a_template_class_can_be_mocked ) BOOST_CHECK( MOCK_VERIFY( some_template_class< int >::some_static_method ) ); MOCK_RESET( some_template_class< int >::some_static_method ); } + +namespace +{ + MOCK_CLASS( mock_class ) + { + MOCK_METHOD_EXT( m, 0, void(), m ); + }; +} + +BOOST_AUTO_TEST_CASE( resetting_referenced_mock_class_does_not_crash ) +{ + MOCK_FUNCTOR( f, mock_class() ); + { + mock_class c; + MOCK_EXPECT( f ).returns( c ); + MOCK_EXPECT( c.m ); + } + mock::reset(); +} + +namespace +{ + MOCK_CLASS( mock_class2 ) + { + MOCK_METHOD_EXT( m, 0, mock_class2(), m ); + }; +} + +BOOST_AUTO_TEST_CASE( resetting_self_referenced_mock_class_does_not_crash ) +{ + { + mock_class2 c; + MOCK_EXPECT( c.m ).returns( c ); + } + mock::reset(); +}