From 0765517141e33f47015b487099d552ac759233de Mon Sep 17 00:00:00 2001 From: ameliabarnabyhub Date: Fri, 14 Aug 2026 10:29:18 +0800 Subject: [PATCH 1/8] feat(gmock): opt-in require NiceMock or StrictMock (#4882) Signed-off-by: ameliabarnabyhub --- .../include/gmock/internal/gmock-port.h | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/googlemock/include/gmock/internal/gmock-port.h b/googlemock/include/gmock/internal/gmock-port.h index 3bf0b818..5aa32919 100644 --- a/googlemock/include/gmock/internal/gmock-port.h +++ b/googlemock/include/gmock/internal/gmock-port.h @@ -57,6 +57,26 @@ #include "gmock/internal/custom/gmock-port.h" #include "gtest/internal/gtest-port.h" +// When set to a non-zero value, gMock rejects naggy (default) mocks: each mock +// must be wrapped in NiceMock/StrictMock, or the mock class must declare +// DEFAULT_TO_NICE() / DEFAULT_TO_STRICT() (see gmock-nice-strict.h). +// Enforcement is header-only and does not change the gMock library ABI; only +// TUs compiled with the macro are affected. Issue #4882. +// +// Enable with either: +// -DGOOGLEMOCK_REQUIRE_STRICT_OR_NICE=1 +// -DGMOCK_FORCE_EXPLICIT_MOCK_KIND=1 +#if !defined(GMOCK_INTERNAL_REQUIRE_STRICT_OR_NICE) +#if (defined(GOOGLEMOCK_REQUIRE_STRICT_OR_NICE) && \ + GOOGLEMOCK_REQUIRE_STRICT_OR_NICE) || \ + (defined(GMOCK_FORCE_EXPLICIT_MOCK_KIND) && \ + GMOCK_FORCE_EXPLICIT_MOCK_KIND) +#define GMOCK_INTERNAL_REQUIRE_STRICT_OR_NICE 1 +#else +#define GMOCK_INTERNAL_REQUIRE_STRICT_OR_NICE 0 +#endif +#endif + #if defined(GTEST_HAS_ABSL) && !defined(GTEST_NO_ABSL_FLAGS) #include "absl/flags/declare.h" #include "absl/flags/flag.h" From 74cf3e25627c0e4b5f835c38516db1123972634a Mon Sep 17 00:00:00 2001 From: ameliabarnabyhub Date: Fri, 14 Aug 2026 10:29:20 +0800 Subject: [PATCH 2/8] feat(gmock): opt-in require NiceMock or StrictMock (#4882) Signed-off-by: ameliabarnabyhub --- googlemock/include/gmock/gmock-nice-strict.h | 37 +++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/googlemock/include/gmock/gmock-nice-strict.h b/googlemock/include/gmock/gmock-nice-strict.h index 5a3537e2..f75e5d48 100644 --- a/googlemock/include/gmock/gmock-nice-strict.h +++ b/googlemock/include/gmock/gmock-nice-strict.h @@ -27,7 +27,8 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Implements class templates NiceMock, NaggyMock, and StrictMock. +// Implements class templates NiceMock, NaggyMock, and StrictMock, and the +// DEFAULT_TO_NICE() / DEFAULT_TO_STRICT() macros (issue #4882). // // Given a mock class MockFoo that is created using Google Mock, // NiceMock is a subclass of MockFoo that allows @@ -44,6 +45,12 @@ // stop behaving like NaggyMock and start behaving like // NiceMock. // +// DEFAULT_TO_NICE() / DEFAULT_TO_STRICT() may be placed in a mock class +// to select nice/strict behavior for bare instances of that class. +// With -DGOOGLEMOCK_REQUIRE_STRICT_OR_NICE=1 (or +// -DGMOCK_FORCE_EXPLICIT_MOCK_KIND=1), naggy mocks are rejected: use a +// NiceMock/StrictMock wrapper or one of those macros. +// // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of // their respective base class. Therefore you can write // NiceMock(5, "a") to construct a nice mock where MockFoo @@ -145,6 +152,28 @@ class [[nodiscard]] StrictMockImpl { } // namespace internal +// Declares that an uninteresting call on this mock class should be allowed +// (nice). Place in a **public** section of the mock class: +// +// class MockFoo : public Foo { +// public: +// DEFAULT_TO_NICE(); +// MOCK_METHOD(void, DoFoo, (), (override)); +// }; +// +// When GOOGLEMOCK_REQUIRE_STRICT_OR_NICE / GMOCK_FORCE_EXPLICIT_MOCK_KIND is +// enabled, either this macro, DEFAULT_TO_STRICT(), or a NiceMock/StrictMock +// wrapper is required (issue #4882). +#define DEFAULT_TO_NICE() \ + ::testing::internal::DefaultMockKindInstaller<::testing::internal::kAllow> \ + gmock_explicit_mock_kind_installer_ + +// Declares that an uninteresting call on this mock class should fail (strict). +// Place in a **public** section of the mock class. +#define DEFAULT_TO_STRICT() \ + ::testing::internal::DefaultMockKindInstaller<::testing::internal::kFail> \ + gmock_explicit_mock_kind_installer_ + template class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock : private internal::NiceMockImpl, @@ -195,6 +224,12 @@ class [[nodiscard]] GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock "strictness modifier. See " "https://google.github.io/googletest/" "gmock_cook_book.html#NiceStrictNaggy"); + static_assert( + !GMOCK_INTERNAL_REQUIRE_STRICT_OR_NICE, + "NaggyMock is disabled when GOOGLEMOCK_REQUIRE_STRICT_OR_NICE or " + "GMOCK_FORCE_EXPLICIT_MOCK_KIND is enabled; use NiceMock, StrictMock, " + "DEFAULT_TO_NICE(), or DEFAULT_TO_STRICT() instead " + "(https://github.com/google/googletest/issues/4882)"); public: NaggyMock() : MockClass() { From f7bf444c1d8ab6f7f37679601429b1a741c513df Mon Sep 17 00:00:00 2001 From: ameliabarnabyhub Date: Fri, 14 Aug 2026 10:29:23 +0800 Subject: [PATCH 3/8] feat(gmock): opt-in require NiceMock or StrictMock (#4882) Signed-off-by: ameliabarnabyhub --- googlemock/include/gmock/gmock-function-mocker.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/googlemock/include/gmock/gmock-function-mocker.h b/googlemock/include/gmock/gmock-function-mocker.h index d2cb13cd..2566ea73 100644 --- a/googlemock/include/gmock/gmock-function-mocker.h +++ b/googlemock/include/gmock/gmock-function-mocker.h @@ -186,6 +186,7 @@ using internal::FunctionMocker; GMOCK_PP_IF(_Final, final, ) { \ GMOCK_MOCKER_(_N, _Constness, _MethodName) \ .SetOwnerAndName(this, #_MethodName); \ + ::testing::internal::EnforceNiceOrStrictMockKind(this); \ return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ .Invoke(GMOCK_PP_REPEAT(GMOCK_INTERNAL_FORWARD_ARG, _Signature, _N)); \ } \ @@ -193,6 +194,7 @@ using internal::FunctionMocker; GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_PARAMETER, _Signature, _N)) \ GMOCK_PP_IF(_Constness, const, ) _RefSpec { \ GMOCK_MOCKER_(_N, _Constness, _MethodName).RegisterOwner(this); \ + ::testing::internal::EnforceNiceOrStrictMockKind(this); \ return GMOCK_MOCKER_(_N, _Constness, _MethodName) \ .With(GMOCK_PP_REPEAT(GMOCK_INTERNAL_MATCHER_ARGUMENT, , _N)); \ } \ From 4aec47b4823547908fdc9976255c9cc473541e13 Mon Sep 17 00:00:00 2001 From: ameliabarnabyhub Date: Fri, 14 Aug 2026 10:29:26 +0800 Subject: [PATCH 4/8] feat(gmock): opt-in require NiceMock or StrictMock (#4882) Signed-off-by: ameliabarnabyhub --- .../include/gmock/gmock-spec-builders.h | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index 1be93588..bb35ee10 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -358,6 +358,12 @@ enum CallReaction { kFail, }; +// Installs DEFAULT_TO_NICE / DEFAULT_TO_STRICT call reactions (see +// gmock-nice-strict.h). Friended by Mock so it can call the private +// Allow/Fail/Unregister APIs. +template +class DefaultMockKindInstaller; + } // namespace internal // Utilities for manipulating mock objects. @@ -406,6 +412,8 @@ class GTEST_API_ Mock { friend class internal::NaggyMockImpl; template friend class internal::StrictMockImpl; + template + friend class internal::DefaultMockKindInstaller; // Tells Google Mock to allow uninteresting calls on the given mock // object. @@ -462,6 +470,84 @@ class GTEST_API_ Mock { GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex); }; // class Mock +namespace internal { + +// Used by DEFAULT_TO_NICE() / DEFAULT_TO_STRICT() to set the uninteresting-call +// reaction for a bare mock instance and clear it on destruction. +template +class DefaultMockKindInstaller { + public: + DefaultMockKindInstaller() = default; + ~DefaultMockKindInstaller() { + if (mock_obj_ != 0) { + Mock::UnregisterCallReaction(mock_obj_); + } + } + + DefaultMockKindInstaller(const DefaultMockKindInstaller&) = delete; + DefaultMockKindInstaller& operator=(const DefaultMockKindInstaller&) = delete; + + void EnsureInstalled(const void* mock_obj) const { + if (mock_obj_ != 0) { + return; + } + mock_obj_ = reinterpret_cast(mock_obj); + if constexpr (kReaction == kAllow) { + Mock::AllowUninterestingCalls(mock_obj_); + } else if constexpr (kReaction == kFail) { + Mock::FailUninterestingCalls(mock_obj_); + } else { + Mock::WarnUninterestingCalls(mock_obj_); + } + } + + private: + mutable uintptr_t mock_obj_ = 0; +}; + +template +struct HasDefaultMockKindInstaller : std::false_type {}; + +template +struct HasDefaultMockKindInstaller< + T, std::void_t().gmock_explicit_mock_kind_installer_)>> + : std::true_type {}; + +// Called from MOCK_METHOD on ON_CALL/EXPECT_CALL and on each mock invocation. +// Installs DEFAULT_TO_* reactions when present. When +// GMOCK_INTERNAL_REQUIRE_STRICT_OR_NICE is enabled, also rejects naggy/bare +// mocks (NiceMock/StrictMock wrappers and DEFAULT_TO_* are allowed). +template +void EnforceNiceOrStrictMockKind(const MockT* mock) { + if constexpr (HasDefaultMockKindInstaller::value) { + void* const mock_obj = + const_cast(static_cast(mock)); + // NiceMock/StrictMock register their reaction in a base before MockClass + // runs; prefer that over DEFAULT_TO_* on the mock class. + if (Mock::IsNice(mock_obj) || Mock::IsStrict(mock_obj)) { + return; + } + mock->gmock_explicit_mock_kind_installer_.EnsureInstalled(mock); + return; + } +#if GMOCK_INTERNAL_REQUIRE_STRICT_OR_NICE + void* const mock_obj = + const_cast(static_cast(mock)); + if (!Mock::IsNice(mock_obj) && !Mock::IsStrict(mock_obj)) { + Assert(false, __FILE__, __LINE__, + "When GOOGLEMOCK_REQUIRE_STRICT_OR_NICE or " + "GMOCK_FORCE_EXPLICIT_MOCK_KIND is enabled, mocks must be wrapped " + "in NiceMock<> or StrictMock<>, or the mock class must declare " + "DEFAULT_TO_NICE() or DEFAULT_TO_STRICT(). See " + "https://github.com/google/googletest/issues/4882"); + } +#else + (void)mock; +#endif +} + +} // namespace internal + // An abstract handle of an expectation. Useful in the .After() // clause of EXPECT_CALL() for setting the (partial) order of // expectations. The syntax: From 9e29a822da4e2742ddfe3e304712de6e491303c3 Mon Sep 17 00:00:00 2001 From: ameliabarnabyhub Date: Fri, 14 Aug 2026 10:29:28 +0800 Subject: [PATCH 5/8] feat(gmock): opt-in require NiceMock or StrictMock (#4882) Signed-off-by: ameliabarnabyhub --- googlemock/test/gmock-nice-strict_test.cc | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/googlemock/test/gmock-nice-strict_test.cc b/googlemock/test/gmock-nice-strict_test.cc index 95f09690..e6c3b97b 100644 --- a/googlemock/test/gmock-nice-strict_test.cc +++ b/googlemock/test/gmock-nice-strict_test.cc @@ -537,5 +537,51 @@ TEST(StrictMockTest, IsNaggy_IsNice_IsStrict) { EXPECT_TRUE(Mock::IsStrict(&strict_foo)); } +class MockFooDefaultNice { + public: + DEFAULT_TO_NICE(); + MOCK_METHOD(void, DoThis, ()); +}; + +class MockFooDefaultStrict { + public: + DEFAULT_TO_STRICT(); + MOCK_METHOD(void, DoThis, ()); +}; + +// DEFAULT_TO_NICE() makes a bare mock behave like NiceMock. +TEST(DefaultToNiceTest, IsNice) { + MockFooDefaultNice mock; + EXPECT_CALL(mock, DoThis()); + mock.DoThis(); + EXPECT_TRUE(Mock::IsNice(&mock)); + EXPECT_FALSE(Mock::IsStrict(&mock)); + EXPECT_FALSE(Mock::IsNaggy(&mock)); +} + +#if GTEST_HAS_STREAM_REDIRECTION +TEST(DefaultToNiceTest, NoWarningForUninterestingCall) { + MockFooDefaultNice mock; + CaptureStdout(); + mock.DoThis(); + EXPECT_EQ("", GetCapturedStdout()); +} +#endif + +// DEFAULT_TO_STRICT() makes a bare mock behave like StrictMock. +TEST(DefaultToStrictTest, IsStrict) { + MockFooDefaultStrict mock; + EXPECT_CALL(mock, DoThis()); + mock.DoThis(); + EXPECT_TRUE(Mock::IsStrict(&mock)); + EXPECT_FALSE(Mock::IsNice(&mock)); + EXPECT_FALSE(Mock::IsNaggy(&mock)); +} + +TEST(DefaultToStrictTest, UninterestingCallFails) { + MockFooDefaultStrict mock; + EXPECT_NONFATAL_FAILURE(mock.DoThis(), "Uninteresting mock function call"); +} + } // namespace gmock_nice_strict_test } // namespace testing From 7611954652c6462b5b264d657dda257eeb2dd7d7 Mon Sep 17 00:00:00 2001 From: ameliabarnabyhub Date: Fri, 14 Aug 2026 10:29:30 +0800 Subject: [PATCH 6/8] feat(gmock): opt-in require NiceMock or StrictMock (#4882) Signed-off-by: ameliabarnabyhub --- .../test/gmock-require-strict-or-nice_test.cc | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 googlemock/test/gmock-require-strict-or-nice_test.cc diff --git a/googlemock/test/gmock-require-strict-or-nice_test.cc b/googlemock/test/gmock-require-strict-or-nice_test.cc new file mode 100644 index 00000000..7ef0551c --- /dev/null +++ b/googlemock/test/gmock-require-strict-or-nice_test.cc @@ -0,0 +1,102 @@ +// Copyright 2025, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Tests GOOGLEMOCK_REQUIRE_STRICT_OR_NICE / GMOCK_FORCE_EXPLICIT_MOCK_KIND +// (https://github.com/google/googletest/issues/4882). + +#define GOOGLEMOCK_REQUIRE_STRICT_OR_NICE 1 + +#include "gmock/gmock.h" +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" + +namespace { + +using ::testing::NiceMock; +using ::testing::StrictMock; + +class MockFoo { + public: + MOCK_METHOD(void, DoThis, ()); +}; + +class MockFooDefaultNice { + public: + DEFAULT_TO_NICE(); + MOCK_METHOD(void, DoThis, ()); +}; + +class MockFooDefaultStrict { + public: + DEFAULT_TO_STRICT(); + MOCK_METHOD(void, DoThis, ()); +}; + +TEST(RequireStrictOrNiceTest, BareMockFailsOnCall) { + MockFoo mock; + EXPECT_FATAL_FAILURE(mock.DoThis(), "GOOGLEMOCK_REQUIRE_STRICT_OR_NICE"); +} + +TEST(RequireStrictOrNiceTest, BareMockFailsOnExpectCall) { + MockFoo mock; + EXPECT_FATAL_FAILURE( + { + EXPECT_CALL(mock, DoThis()); + }, + "GOOGLEMOCK_REQUIRE_STRICT_OR_NICE"); +} + +TEST(RequireStrictOrNiceTest, NiceMockAllowed) { + NiceMock mock; + EXPECT_CALL(mock, DoThis()); + mock.DoThis(); + EXPECT_TRUE(testing::Mock::IsNice(&mock)); +} + +TEST(RequireStrictOrNiceTest, StrictMockAllowed) { + StrictMock mock; + EXPECT_CALL(mock, DoThis()); + mock.DoThis(); + EXPECT_TRUE(testing::Mock::IsStrict(&mock)); +} + +TEST(RequireStrictOrNiceTest, DefaultToNiceAllowed) { + MockFooDefaultNice mock; + mock.DoThis(); // uninteresting, but nice + EXPECT_TRUE(testing::Mock::IsNice(&mock)); +} + +TEST(RequireStrictOrNiceTest, DefaultToStrictAllowed) { + MockFooDefaultStrict mock; + EXPECT_CALL(mock, DoThis()); + mock.DoThis(); + EXPECT_TRUE(testing::Mock::IsStrict(&mock)); +} + +} // namespace From a2a61a94581238e26ec4c02b955cc3e46e378b33 Mon Sep 17 00:00:00 2001 From: ameliabarnabyhub Date: Fri, 14 Aug 2026 10:29:32 +0800 Subject: [PATCH 7/8] feat(gmock): opt-in require NiceMock or StrictMock (#4882) Signed-off-by: ameliabarnabyhub --- googlemock/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/googlemock/CMakeLists.txt b/googlemock/CMakeLists.txt index 33ec9636..ca7df698 100644 --- a/googlemock/CMakeLists.txt +++ b/googlemock/CMakeLists.txt @@ -149,6 +149,7 @@ if (gmock_build_tests) cxx_test(gmock-matchers-misc_test gmock_main) cxx_test(gmock-more-actions_test gmock_main) cxx_test(gmock-nice-strict_test gmock_main) + cxx_test(gmock-require-strict-or-nice_test gmock_main) cxx_test(gmock-port_test gmock_main) cxx_test(gmock-spec-builders_test gmock_main) cxx_test(gmock_link_test gmock_main test/gmock_link2_test.cc) From 3c4dd13cbad333073a85c94c207e6eb2351934f5 Mon Sep 17 00:00:00 2001 From: ameliabarnabyhub Date: Fri, 14 Aug 2026 10:29:34 +0800 Subject: [PATCH 8/8] feat(gmock): opt-in require NiceMock or StrictMock (#4882) Signed-off-by: ameliabarnabyhub --- docs/gmock_cook_book.md | 50 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/docs/gmock_cook_book.md b/docs/gmock_cook_book.md index cee1da8e..64e4ecb3 100644 --- a/docs/gmock_cook_book.md +++ b/docs/gmock_cook_book.md @@ -488,6 +488,56 @@ nice mocks (not yet the default) most of the time, use naggy mocks (the current default) when developing or debugging tests, and use strict mocks only as the last resort. +### Requiring NiceMock or StrictMock {#RequireNiceOrStrict} + +Large projects often want to ban naggy (default) mocks because warnings are easy +to miss and hard to interpret. gMock supports an opt-in compile definition that +forces an explicit choice between nice and strict behavior +([issue #4882](https://github.com/google/googletest/issues/4882)): + +``` +-DGOOGLEMOCK_REQUIRE_STRICT_OR_NICE=1 +``` + +or equivalently: + +``` +-DGMOCK_FORCE_EXPLICIT_MOCK_KIND=1 +``` + +With that define set in a translation unit: + +* `NiceMock` and `StrictMock` work as usual. +* `NaggyMock` fails to compile. +* A bare `MockFoo` fails at the first `ON_CALL` / `EXPECT_CALL` or mock-method + call unless the mock class declares a default: + +```cpp +class MockFoo : public Foo { + public: + DEFAULT_TO_STRICT(); // or DEFAULT_TO_NICE(); + + MOCK_METHOD(void, DoFoo, (), (override)); +}; +``` + +`DEFAULT_TO_NICE()` / `DEFAULT_TO_STRICT()` also work without the define: they +make a bare `MockFoo` behave like `NiceMock` / `StrictMock`. + +Upgrade path for existing codebases: + +```cpp +#define TODO_CHOOSE_NICE_OR_STRICT() DEFAULT_TO_NICE() +``` + +Add `TODO_CHOOSE_NICE_OR_STRICT();` to every mock class, then enable +`-DGOOGLEMOCK_REQUIRE_STRICT_OR_NICE=1`, then gradually replace the TODOs with +real choices (or wrap instances in `NiceMock` / `StrictMock`). + +The define is header-only and does not change the gMock library ABI; only +translation units compiled with it are affected. Subprojects can keep building +without the define. + ### Simplifying the Interface without Breaking Existing Code {#SimplerInterfaces} Sometimes a method has a long list of arguments that is mostly uninteresting.