@@ -456,7 +456,8 @@ static CallReaction intToCallReaction(int mock_behavior) {
456456
457457namespace {
458458
459- typedef std::set<internal::UntypedFunctionMockerBase*> FunctionMockers;
459+ // Modern alias for FunctionMockers
460+ using FunctionMockers = std::set<internal::UntypedFunctionMockerBase*>;
460461
461462// The current state of a mock object. Such information is needed for
462463// detecting leaked mock objects and explicitly verifying a mock's
@@ -473,6 +474,8 @@ struct MockObjectState {
473474 ::std::string first_used_test;
474475 bool leakable; // true if and only if it's OK to leak the object.
475476 FunctionMockers function_mockers; // All registered methods of the object.
477+
478+ const std::type_info* mock_type; // Dynamic mock type (if registered)
476479};
477480
478481// A global registry holding the state of all mock objects that are
@@ -481,13 +484,22 @@ struct MockObjectState {
481484// is removed from the registry in the mock object's destructor.
482485class MockObjectRegistry {
483486 public:
484- // Maps a mock object (identified by its address) to its state.
485- typedef std::map<const void *, MockObjectState> StateMap;
487+ // New alias for StateMap
488+ using StateMap = std::map<const void *, MockObjectState>;
489+
490+ // New method to register the type of mock
491+ template <typename MockClass>
492+ void RegisterMockType (const void * mock_obj) {
493+ internal::MutexLock l (&internal::g_gmock_mutex);
494+ StateMap::iterator it = states_.find (mock_obj);
495+ if (it != states_.end ()) {
496+ it->second .mock_type = &typeid (*static_cast <const MockClass*>(mock_obj));
497+ }
498+ }
486499
487- // This destructor will be called when a program exits, after all
488- // tests in it have been run. By then, there should be no mock
489- // object alive. Therefore we report any living object as test
490- // failure, unless the user explicitly asked us to ignore it.
500+ // This destructor will be called when the program exits, after all tests have run.
501+ // At that point, there should be no live mock objects. Therefore, we report any still-live object as
502+ // a test failure, unless the user has explicitly asked to ignore it.
491503 ~MockObjectRegistry () {
492504 if (!GMOCK_FLAG_GET (catch_leaked_mocks)) return ;
493505 internal::MutexLock l (&internal::g_gmock_mutex);
@@ -498,9 +510,12 @@ class MockObjectRegistry {
498510 if (it->second .leakable ) // The user said it's fine to leak this object.
499511 continue ;
500512
501- // FIXME: Print the type of the leaked object.
502- // This can help the user identify the leaked object.
503- std::cout << " \n " ;
513+ // Print the type of the leaked object, if available
514+ std::string type_name = " <unknown>" ;
515+ if (it->second .mock_type ) {
516+ type_name = it->second .mock_type ->name ();
517+ }
518+ ::std::cerr << " ERROR: Leaked mock object of type: " << type_name << " \n " ;
504519 const MockObjectState& state = it->second ;
505520 std::cout << internal::FormatFileLocation (state.first_used_file ,
506521 state.first_used_line );
@@ -575,14 +590,14 @@ void Mock::AllowUninterestingCalls(uintptr_t mock_obj)
575590// Tells Google Mock to warn the user about uninteresting calls on the
576591// given mock object.
577592void Mock::WarnUninterestingCalls (uintptr_t mock_obj)
578- GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex ) {
593+ GTEST_LOCK_EXCLUDED_(internal::gmock_mutex ) {
579594 SetReactionOnUninterestingCalls (mock_obj, internal::kWarn );
580595}
581596
582597// Tells Google Mock to fail uninteresting calls on the given mock
583598// object.
584599void Mock::FailUninterestingCalls (uintptr_t mock_obj)
585- GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex ) {
600+ GTEST_LOCK_EXCLUDED_(internal::gmock_mutex ) {
586601 SetReactionOnUninterestingCalls (mock_obj, internal::kFail );
587602}
588603
0 commit comments