Path: blob/main/contrib/googletest/googlemock/include/gmock/gmock-nice-strict.h
48375 views
// Copyright 2008, Google Inc.1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions are5// met:6//7// * Redistributions of source code must retain the above copyright8// notice, this list of conditions and the following disclaimer.9// * Redistributions in binary form must reproduce the above10// copyright notice, this list of conditions and the following disclaimer11// in the documentation and/or other materials provided with the12// distribution.13// * Neither the name of Google Inc. nor the names of its14// contributors may be used to endorse or promote products derived from15// this software without specific prior written permission.16//17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT19// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR20// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT21// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,22// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT23// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,24// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY25// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT26// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE27// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2829// Implements class templates NiceMock, NaggyMock, and StrictMock.30//31// Given a mock class MockFoo that is created using Google Mock,32// NiceMock<MockFoo> is a subclass of MockFoo that allows33// uninteresting calls (i.e. calls to mock methods that have no34// EXPECT_CALL specs), NaggyMock<MockFoo> is a subclass of MockFoo35// that prints a warning when an uninteresting call occurs, and36// StrictMock<MockFoo> is a subclass of MockFoo that treats all37// uninteresting calls as errors.38//39// Currently a mock is naggy by default, so MockFoo and40// NaggyMock<MockFoo> behave like the same. However, we will soon41// switch the default behavior of mocks to be nice, as that in general42// leads to more maintainable tests. When that happens, MockFoo will43// stop behaving like NaggyMock<MockFoo> and start behaving like44// NiceMock<MockFoo>.45//46// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of47// their respective base class. Therefore you can write48// NiceMock<MockFoo>(5, "a") to construct a nice mock where MockFoo49// has a constructor that accepts (int, const char*), for example.50//51// A known limitation is that NiceMock<MockFoo>, NaggyMock<MockFoo>,52// and StrictMock<MockFoo> only works for mock methods defined using53// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class.54// If a mock method is defined in a base class of MockFoo, the "nice"55// or "strict" modifier may not affect it, depending on the compiler.56// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT57// supported.5859// IWYU pragma: private, include "gmock/gmock.h"60// IWYU pragma: friend gmock/.*6162#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_63#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_6465#include <cstdint>66#include <type_traits>6768#include "gmock/gmock-spec-builders.h"69#include "gmock/internal/gmock-port.h"7071namespace testing {72template <class MockClass>73class NiceMock;74template <class MockClass>75class NaggyMock;76template <class MockClass>77class StrictMock;7879namespace internal {80template <typename T>81std::true_type StrictnessModifierProbe(const NiceMock<T>&);82template <typename T>83std::true_type StrictnessModifierProbe(const NaggyMock<T>&);84template <typename T>85std::true_type StrictnessModifierProbe(const StrictMock<T>&);86std::false_type StrictnessModifierProbe(...);8788template <typename T>89constexpr bool HasStrictnessModifier() {90return decltype(StrictnessModifierProbe(std::declval<const T&>()))::value;91}9293// Base classes that register and deregister with testing::Mock to alter the94// default behavior around uninteresting calls. Inheriting from one of these95// classes first and then MockClass ensures the MockClass constructor is run96// after registration, and that the MockClass destructor runs before97// deregistration. This guarantees that MockClass's constructor and destructor98// run with the same level of strictness as its instance methods.99100#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) && \101(defined(_MSC_VER) || defined(__clang__))102// We need to mark these classes with this declspec to ensure that103// the empty base class optimization is performed.104#define GTEST_INTERNAL_EMPTY_BASE_CLASS __declspec(empty_bases)105#else106#define GTEST_INTERNAL_EMPTY_BASE_CLASS107#endif108109template <typename Base>110class NiceMockImpl {111public:112NiceMockImpl() {113::testing::Mock::AllowUninterestingCalls(reinterpret_cast<uintptr_t>(this));114}115116~NiceMockImpl() {117::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));118}119};120121template <typename Base>122class NaggyMockImpl {123public:124NaggyMockImpl() {125::testing::Mock::WarnUninterestingCalls(reinterpret_cast<uintptr_t>(this));126}127128~NaggyMockImpl() {129::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));130}131};132133template <typename Base>134class StrictMockImpl {135public:136StrictMockImpl() {137::testing::Mock::FailUninterestingCalls(reinterpret_cast<uintptr_t>(this));138}139140~StrictMockImpl() {141::testing::Mock::UnregisterCallReaction(reinterpret_cast<uintptr_t>(this));142}143};144145} // namespace internal146147template <class MockClass>148class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock149: private internal::NiceMockImpl<MockClass>,150public MockClass {151public:152static_assert(!internal::HasStrictnessModifier<MockClass>(),153"Can't apply NiceMock to a class hierarchy that already has a "154"strictness modifier. See "155"https://google.github.io/googletest/"156"gmock_cook_book.html#NiceStrictNaggy");157NiceMock() : MockClass() {158static_assert(sizeof(*this) == sizeof(MockClass),159"The impl subclass shouldn't introduce any padding");160}161162// Ideally, we would inherit base class's constructors through a using163// declaration, which would preserve their visibility. However, many existing164// tests rely on the fact that current implementation reexports protected165// constructors as public. These tests would need to be cleaned up first.166167// Single argument constructor is special-cased so that it can be168// made explicit.169template <typename A>170explicit NiceMock(A&& arg) : MockClass(std::forward<A>(arg)) {171static_assert(sizeof(*this) == sizeof(MockClass),172"The impl subclass shouldn't introduce any padding");173}174175template <typename TArg1, typename TArg2, typename... An>176NiceMock(TArg1&& arg1, TArg2&& arg2, An&&... args)177: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),178std::forward<An>(args)...) {179static_assert(sizeof(*this) == sizeof(MockClass),180"The impl subclass shouldn't introduce any padding");181}182183private:184NiceMock(const NiceMock&) = delete;185NiceMock& operator=(const NiceMock&) = delete;186};187188template <class MockClass>189class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock190: private internal::NaggyMockImpl<MockClass>,191public MockClass {192static_assert(!internal::HasStrictnessModifier<MockClass>(),193"Can't apply NaggyMock to a class hierarchy that already has a "194"strictness modifier. See "195"https://google.github.io/googletest/"196"gmock_cook_book.html#NiceStrictNaggy");197198public:199NaggyMock() : MockClass() {200static_assert(sizeof(*this) == sizeof(MockClass),201"The impl subclass shouldn't introduce any padding");202}203204// Ideally, we would inherit base class's constructors through a using205// declaration, which would preserve their visibility. However, many existing206// tests rely on the fact that current implementation reexports protected207// constructors as public. These tests would need to be cleaned up first.208209// Single argument constructor is special-cased so that it can be210// made explicit.211template <typename A>212explicit NaggyMock(A&& arg) : MockClass(std::forward<A>(arg)) {213static_assert(sizeof(*this) == sizeof(MockClass),214"The impl subclass shouldn't introduce any padding");215}216217template <typename TArg1, typename TArg2, typename... An>218NaggyMock(TArg1&& arg1, TArg2&& arg2, An&&... args)219: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),220std::forward<An>(args)...) {221static_assert(sizeof(*this) == sizeof(MockClass),222"The impl subclass shouldn't introduce any padding");223}224225private:226NaggyMock(const NaggyMock&) = delete;227NaggyMock& operator=(const NaggyMock&) = delete;228};229230template <class MockClass>231class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock232: private internal::StrictMockImpl<MockClass>,233public MockClass {234public:235static_assert(236!internal::HasStrictnessModifier<MockClass>(),237"Can't apply StrictMock to a class hierarchy that already has a "238"strictness modifier. See "239"https://google.github.io/googletest/"240"gmock_cook_book.html#NiceStrictNaggy");241StrictMock() : MockClass() {242static_assert(sizeof(*this) == sizeof(MockClass),243"The impl subclass shouldn't introduce any padding");244}245246// Ideally, we would inherit base class's constructors through a using247// declaration, which would preserve their visibility. However, many existing248// tests rely on the fact that current implementation reexports protected249// constructors as public. These tests would need to be cleaned up first.250251// Single argument constructor is special-cased so that it can be252// made explicit.253template <typename A>254explicit StrictMock(A&& arg) : MockClass(std::forward<A>(arg)) {255static_assert(sizeof(*this) == sizeof(MockClass),256"The impl subclass shouldn't introduce any padding");257}258259template <typename TArg1, typename TArg2, typename... An>260StrictMock(TArg1&& arg1, TArg2&& arg2, An&&... args)261: MockClass(std::forward<TArg1>(arg1), std::forward<TArg2>(arg2),262std::forward<An>(args)...) {263static_assert(sizeof(*this) == sizeof(MockClass),264"The impl subclass shouldn't introduce any padding");265}266267private:268StrictMock(const StrictMock&) = delete;269StrictMock& operator=(const StrictMock&) = delete;270};271272#undef GTEST_INTERNAL_EMPTY_BASE_CLASS273274} // namespace testing275276#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_277278279