This commit is contained in:
jdfa 2025-03-28 14:55:09 +01:00 committed by GitHub
commit 708653597e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 60 additions and 7 deletions

View file

@ -189,6 +189,14 @@ expectations must be matched in a given order, you can use the
[`InSequence` clause](reference/mocking.md#EXPECT_CALL.InSequence) of
`EXPECT_CALL`, or use an [`InSequence` object](reference/mocking.md#InSequence).
## Distinguishing between Unintresting Calls from Different Mocks
By default unintresting mock function calls will be logged as function name and its address.
In case when multiple instances of same mocked class is used it can be useful to set mock name:
```cpp
Mock::SetMockName(&mock_obj, "NamedObject");
```
## Verifying and Resetting a Mock
gMock will verify the expectations on a mock object when it is destructed, or

View file

@ -382,6 +382,15 @@ class GTEST_API_ Mock {
static bool VerifyAndClear(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Set name for mock. Will be used in output.
// Useful when multiple instances of same mock is required.
static void SetMockName(void* mock_obj, const std::string& mock_name)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Returns mock name which was set using SetMockName
static std::string GetMockName(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
// Returns whether the mock was created as a naggy mock (default)
static bool IsNaggy(void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex);
@ -1622,6 +1631,8 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
DescribeDefaultActionTo(args, os);
*os << " Function call: " << Name();
UniversalPrint(args, os);
const auto mock_name = Mock::GetMockName(MockObject());
if (!mock_name.empty()) *os << " on " << mock_name;
}
// Returns the expectation that matches the given function arguments

View file

@ -471,6 +471,7 @@ struct MockObjectState {
int first_used_line;
::std::string first_used_test_suite;
::std::string first_used_test;
::std::string name;
bool leakable; // true if and only if it's OK to leak the object.
FunctionMockers function_mockers; // All registered methods of the object.
};
@ -634,6 +635,22 @@ bool Mock::VerifyAndClear(void* mock_obj)
return VerifyAndClearExpectationsLocked(mock_obj);
}
// Set name for mock. Will be used in output.
// Useful when multiple instances of same mock is required.
void Mock::SetMockName(void* mock_obj, const std::string& mock_name)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
g_mock_object_registry.states()[mock_obj].name = mock_name;
}
// Returns mock name which was set using SetMockName
std::string Mock::GetMockName(const void* mock_obj)
GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) {
internal::MutexLock l(&internal::g_gmock_mutex);
if (g_mock_object_registry.states().count(mock_obj) == 0) return "";
return g_mock_object_registry.states()[mock_obj].name;
}
// Verifies and clears all expectations on the given mock object. If
// the expectations aren't satisfied, generates one or more Google
// Test non-fatal failures and returns false.
@ -712,14 +729,13 @@ void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker)
internal::g_gmock_mutex.AssertHeld();
for (MockObjectRegistry::StateMap::iterator it =
g_mock_object_registry.states().begin();
it != g_mock_object_registry.states().end(); ++it) {
it != g_mock_object_registry.states().end();) {
FunctionMockers& mockers = it->second.function_mockers;
if (mockers.erase(mocker) > 0) {
// mocker was in mockers and has been just removed.
if (mockers.empty()) {
g_mock_object_registry.states().erase(it);
}
return;
mockers.erase(mocker);
if (mockers.empty()) {
it = g_mock_object_registry.states().erase(it);
} else {
++it;
}
}
}

View file

@ -190,6 +190,24 @@ TEST(RawMockTest, InfoForUninterestingCall) {
GMOCK_FLAG_SET(verbose, saved_flag);
}
// Tests that a raw mock using mock name in warnings for uninteresting calls.
TEST(RawMockTest, NamedMockInUninteresingCall) {
MockFoo raw_foo;
const std::string saved_flag = GMOCK_FLAG_GET(verbose);
GMOCK_FLAG_SET(verbose, "info");
const std::string test_name = "NamedMock";
Mock::SetMockName(&raw_foo, test_name);
CaptureStdout();
raw_foo.DoThis();
ASSERT_THAT(GetCapturedStdout(),
HasSubstr("Uninteresting mock function call"));
EXPECT_THAT(GetCapturedStdout(), HasSubstr(test_name));
GMOCK_FLAG_SET(verbose, saved_flag);
}
TEST(RawMockTest, IsNaggy_IsNice_IsStrict) {
MockFoo raw_foo;
EXPECT_TRUE(Mock::IsNaggy(&raw_foo));