1 // Copyright 2008, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 // Implements class templates NiceMock, NaggyMock, and StrictMock. 31 // 32 // Given a mock class MockFoo that is created using Google Mock, 33 // NiceMock<MockFoo> is a subclass of MockFoo that allows 34 // uninteresting calls (i.e. calls to mock methods that have no 35 // EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo 36 // that prints a warning when an uninteresting call occurs, and 37 // StrictMock<MockFoo> is a subclass of MockFoo that treats all 38 // uninteresting calls as errors. 39 // 40 // Currently a mock is naggy by default, so MockFoo and 41 // NaggyMock<MockFoo> behave like the same. However, we will soon 42 // switch the default behavior of mocks to be nice, as that in general 43 // leads to more maintainable tests. When that happens, MockFoo will 44 // stop behaving like NaggyMock<MockFoo> and start behaving like 45 // NiceMock<MockFoo>. 46 // 47 // NiceMock, NaggyMock, and StrictMock "inherit" the constructors of 48 // their respective base class. Therefore you can write 49 // NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo 50 // has a constructor that accepts (int, const char*), for example. 51 // 52 // A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>, 53 // and StrictMock<MockFoo> only works for mock methods defined using 54 // the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. 55 // If a mock method is defined in a base class of MockFoo, the "nice" 56 // or "strict" modifier may not affect it, depending on the compiler. 57 // In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT 58 // supported. 59 60 // IWYU pragma: private, include "gmock/gmock.h" 61 // IWYU pragma: friend gmock/.* 62 63 #ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ 64 #define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ 65 66 #include <cstdint> 67 #include <type_traits> 68 69 #include "gmock/gmock-spec-builders.h" 70 #include "gmock/internal/gmock-port.h" 71 72 namespace testing { 73 template <class MockClass> 74 class NiceMock; 75 template <class MockClass> 76 class NaggyMock; 77 template <class MockClass> 78 class StrictMock; 79 80 namespace internal { 81 template <typename T> 82 std::true_type StrictnessModifierProbe(const NiceMock<T>&); 83 template <typename T> 84 std::true_type StrictnessModifierProbe(const NaggyMock<T>&); 85 template <typename T> 86 std::true_type StrictnessModifierProbe(const StrictMock<T>&); 87 std::false_type StrictnessModifierProbe(...); 88 89 template <typename T> 90 constexpr bool HasStrictnessModifier() { 91 return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value; 92 } 93 94 // Base classes that register and deregister with testing::Mock to alter the 95 // default behavior around uninteresting calls. Inheriting from one of these 96 // classes first and then MockClass ensures the MockClass constructor is run 97 // after registration, and that the MockClass destructor runs before 98 // deregistration. This guarantees that MockClass's constructor and destructor 99 // run with the same level of strictness as its instance methods. 100 101 #if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \ 102 (defined(_MSC_VER) || defined(__clang__)) 103 // We need to mark these classes with this declspec to ensure that 104 // the empty base class optimization is performed. 105 #define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases) 106 #else 107 #define GTEST_INTERNAL_EMPTY_BASE_CLASS 108 #endif 109 110 template <typename Base> 111 class NiceMockImpl { 112 public: 113 NiceMockImpl() { 114 ::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this)); 115 } 116 117 ~NiceMockImpl() { 118 ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this)); 119 } 120 }; 121 122 template <typename Base> 123 class NaggyMockImpl { 124 public: 125 NaggyMockImpl() { 126 ::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this)); 127 } 128 129 ~NaggyMockImpl() { 130 ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this)); 131 } 132 }; 133 134 template <typename Base> 135 class StrictMockImpl { 136 public: 137 StrictMockImpl() { 138 ::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this)); 139 } 140 141 ~StrictMockImpl() { 142 ::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this)); 143 } 144 }; 145 146 } // namespace internal 147 148 template <class MockClass> 149 class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock 150 : private internal::NiceMockImpl<MockClass>, 151 public MockClass { 152 public: 153 static_assert(!internal::HasStrictnessModifier<MockClass>(), 154 "Can't apply NiceMock to a class hierarchy that already has a " 155 "strictness modifier. See " 156 "https://google.github.io/googletest/" 157 "gmock_cook_book.html#NiceStrictNaggy"); 158 NiceMock() : MockClass() { 159 static_assert(sizeof(*this) == sizeof(MockClass), 160 "The impl subclass shouldn't introduce any padding"); 161 } 162 163 // Ideally, we would inherit base class's constructors through a using 164 // declaration, which would preserve their visibility. However, many existing 165 // tests rely on the fact that current implementation reexports protected 166 // constructors as public. These tests would need to be cleaned up first. 167 168 // Single argument constructor is special-cased so that it can be 169 // made explicit. 170 template <typename A> 171 explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) { 172 static_assert(sizeof(*this) == sizeof(MockClass), 173 "The impl subclass shouldn't introduce any padding"); 174 } 175 176 template <typename TArg1, typename TArg2, typename... An> 177 NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args) 178 : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2), 179 std::forward<An>(args)...) { 180 static_assert(sizeof(*this) == sizeof(MockClass), 181 "The impl subclass shouldn't introduce any padding"); 182 } 183 184 private: 185 NiceMock(const NiceMock&) = delete; 186 NiceMock& operator=(const NiceMock&) = delete; 187 }; 188 189 template <class MockClass> 190 class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock 191 : private internal::NaggyMockImpl<MockClass>, 192 public MockClass { 193 static_assert(!internal::HasStrictnessModifier<MockClass>(), 194 "Can't apply NaggyMock to a class hierarchy that already has a " 195 "strictness modifier. See " 196 "https://google.github.io/googletest/" 197 "gmock_cook_book.html#NiceStrictNaggy"); 198 199 public: 200 NaggyMock() : MockClass() { 201 static_assert(sizeof(*this) == sizeof(MockClass), 202 "The impl subclass shouldn't introduce any padding"); 203 } 204 205 // Ideally, we would inherit base class's constructors through a using 206 // declaration, which would preserve their visibility. However, many existing 207 // tests rely on the fact that current implementation reexports protected 208 // constructors as public. These tests would need to be cleaned up first. 209 210 // Single argument constructor is special-cased so that it can be 211 // made explicit. 212 template <typename A> 213 explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) { 214 static_assert(sizeof(*this) == sizeof(MockClass), 215 "The impl subclass shouldn't introduce any padding"); 216 } 217 218 template <typename TArg1, typename TArg2, typename... An> 219 NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args) 220 : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2), 221 std::forward<An>(args)...) { 222 static_assert(sizeof(*this) == sizeof(MockClass), 223 "The impl subclass shouldn't introduce any padding"); 224 } 225 226 private: 227 NaggyMock(const NaggyMock&) = delete; 228 NaggyMock& operator=(const NaggyMock&) = delete; 229 }; 230 231 template <class MockClass> 232 class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock 233 : private internal::StrictMockImpl<MockClass>, 234 public MockClass { 235 public: 236 static_assert( 237 !internal::HasStrictnessModifier<MockClass>(), 238 "Can't apply StrictMock to a class hierarchy that already has a " 239 "strictness modifier. See " 240 "https://google.github.io/googletest/" 241 "gmock_cook_book.html#NiceStrictNaggy"); 242 StrictMock() : MockClass() { 243 static_assert(sizeof(*this) == sizeof(MockClass), 244 "The impl subclass shouldn't introduce any padding"); 245 } 246 247 // Ideally, we would inherit base class's constructors through a using 248 // declaration, which would preserve their visibility. However, many existing 249 // tests rely on the fact that current implementation reexports protected 250 // constructors as public. These tests would need to be cleaned up first. 251 252 // Single argument constructor is special-cased so that it can be 253 // made explicit. 254 template <typename A> 255 explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) { 256 static_assert(sizeof(*this) == sizeof(MockClass), 257 "The impl subclass shouldn't introduce any padding"); 258 } 259 260 template <typename TArg1, typename TArg2, typename... An> 261 StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args) 262 : MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2), 263 std::forward<An>(args)...) { 264 static_assert(sizeof(*this) == sizeof(MockClass), 265 "The impl subclass shouldn't introduce any padding"); 266 } 267 268 private: 269 StrictMock(const StrictMock&) = delete; 270 StrictMock& operator=(const StrictMock&) = delete; 271 }; 272 273 #undef GTEST_INTERNAL_EMPTY_BASE_CLASS 274 275 } // namespace testing 276 277 #endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ 278