Path: blob/main/contrib/googletest/googlemock/test/gmock-function-mocker_test.cc
48254 views
// Copyright 2007, 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// Google Mock - a framework for writing C++ mock classes.30//31// This file tests the function mocker classes.32#include "gmock/gmock-function-mocker.h"3334// Silence C4503 (decorated name length exceeded) for MSVC.35GTEST_DISABLE_MSC_WARNINGS_PUSH_(4503)3637#ifdef GTEST_OS_WINDOWS38// MSDN says the header file to be included for STDMETHOD is BaseTyps.h but39// we are getting compiler errors if we use basetyps.h, hence including40// objbase.h for definition of STDMETHOD.41#include <objbase.h>42#endif // GTEST_OS_WINDOWS4344#include <functional>45#include <map>46#include <string>47#include <type_traits>4849#include "gmock/gmock.h"50#include "gtest/gtest.h"5152namespace testing {53namespace gmock_function_mocker_test {5455using testing::_;56using testing::A;57using testing::An;58using testing::AnyNumber;59using testing::Const;60using testing::DoDefault;61using testing::Eq;62using testing::Lt;63using testing::MockFunction;64using testing::Ref;65using testing::Return;66using testing::ReturnRef;67using testing::TypedEq;6869template <typename T>70class TemplatedCopyable {71public:72TemplatedCopyable() = default;7374template <typename U>75TemplatedCopyable(const U& other) {} // NOLINT76};7778class FooInterface {79public:80virtual ~FooInterface() = default;8182virtual void VoidReturning(int x) = 0;8384virtual int Nullary() = 0;85virtual bool Unary(int x) = 0;86virtual long Binary(short x, int y) = 0; // NOLINT87virtual int Decimal(bool b, char c, short d, int e, long f, // NOLINT88float g, double h, unsigned i, char* j,89const std::string& k) = 0;9091virtual bool TakesNonConstReference(int& n) = 0; // NOLINT92virtual std::string TakesConstReference(const int& n) = 0;93virtual bool TakesConst(const int x) = 0;9495virtual int OverloadedOnArgumentNumber() = 0;96virtual int OverloadedOnArgumentNumber(int n) = 0;9798virtual int OverloadedOnArgumentType(int n) = 0;99virtual char OverloadedOnArgumentType(char c) = 0;100101virtual int OverloadedOnConstness() = 0;102virtual char OverloadedOnConstness() const = 0;103104virtual int TypeWithHole(int (*func)()) = 0;105virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 0;106virtual int TypeWithTemplatedCopyCtor(const TemplatedCopyable<int>&) = 0;107108virtual int (*ReturnsFunctionPointer1(int))(bool) = 0;109using fn_ptr = int (*)(bool);110virtual fn_ptr ReturnsFunctionPointer2(int) = 0;111112virtual int RefQualifiedConstRef() const& = 0;113virtual int RefQualifiedConstRefRef() const&& = 0;114virtual int RefQualifiedRef() & = 0;115virtual int RefQualifiedRefRef() && = 0;116117virtual int RefQualifiedOverloaded() const& = 0;118virtual int RefQualifiedOverloaded() const&& = 0;119virtual int RefQualifiedOverloaded() & = 0;120virtual int RefQualifiedOverloaded() && = 0;121122#ifdef GTEST_OS_WINDOWS123STDMETHOD_(int, CTNullary)() = 0;124STDMETHOD_(bool, CTUnary)(int x) = 0;125STDMETHOD_(int, CTDecimal)126(bool b, char c, short d, int e, long f, // NOLINT127float g, double h, unsigned i, char* j, const std::string& k) = 0;128STDMETHOD_(char, CTConst)(int x) const = 0;129#endif // GTEST_OS_WINDOWS130};131132// Const qualifiers on arguments were once (incorrectly) considered133// significant in determining whether two virtual functions had the same134// signature. This was fixed in Visual Studio 2008. However, the compiler135// still emits a warning that alerts about this change in behavior.136GTEST_DISABLE_MSC_WARNINGS_PUSH_(4373)137class MockFoo : public FooInterface {138public:139MockFoo() = default;140141// Makes sure that a mock function parameter can be named.142MOCK_METHOD(void, VoidReturning, (int n)); // NOLINT143144MOCK_METHOD(int, Nullary, ()); // NOLINT145146// Makes sure that a mock function parameter can be unnamed.147MOCK_METHOD(bool, Unary, (int)); // NOLINT148MOCK_METHOD(long, Binary, (short, int)); // NOLINT149MOCK_METHOD(int, Decimal,150(bool, char, short, int, long, float, // NOLINT151double, unsigned, char*, const std::string& str),152(override));153154MOCK_METHOD(bool, TakesNonConstReference, (int&)); // NOLINT155MOCK_METHOD(std::string, TakesConstReference, (const int&));156MOCK_METHOD(bool, TakesConst, (const int)); // NOLINT157158// Tests that the function return type can contain unprotected comma.159MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (), ());160MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (int),161(const)); // NOLINT162163MOCK_METHOD(int, OverloadedOnArgumentNumber, ()); // NOLINT164MOCK_METHOD(int, OverloadedOnArgumentNumber, (int)); // NOLINT165166MOCK_METHOD(int, OverloadedOnArgumentType, (int)); // NOLINT167MOCK_METHOD(char, OverloadedOnArgumentType, (char)); // NOLINT168169MOCK_METHOD(int, OverloadedOnConstness, (), (override)); // NOLINT170MOCK_METHOD(char, OverloadedOnConstness, (), (override, const)); // NOLINT171172MOCK_METHOD(int, TypeWithHole, (int (*)()), ()); // NOLINT173MOCK_METHOD(int, TypeWithComma, ((const std::map<int, std::string>&)));174MOCK_METHOD(int, TypeWithTemplatedCopyCtor,175(const TemplatedCopyable<int>&)); // NOLINT176177MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());178MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());179180#ifdef GTEST_OS_WINDOWS181MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE)));182MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE)));183MOCK_METHOD(int, CTDecimal,184(bool b, char c, short d, int e, long f, float g, double h,185unsigned i, char* j, const std::string& k),186(Calltype(STDMETHODCALLTYPE)));187MOCK_METHOD(char, CTConst, (int), (const, Calltype(STDMETHODCALLTYPE)));188MOCK_METHOD((std::map<int, std::string>), CTReturnTypeWithComma, (),189(Calltype(STDMETHODCALLTYPE)));190#endif // GTEST_OS_WINDOWS191192// Test reference qualified functions.193MOCK_METHOD(int, RefQualifiedConstRef, (), (const, ref(&), override));194MOCK_METHOD(int, RefQualifiedConstRefRef, (), (const, ref(&&), override));195MOCK_METHOD(int, RefQualifiedRef, (), (ref(&), override));196MOCK_METHOD(int, RefQualifiedRefRef, (), (ref(&&), override));197198MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&), override));199MOCK_METHOD(int, RefQualifiedOverloaded, (), (const, ref(&&), override));200MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&), override));201MOCK_METHOD(int, RefQualifiedOverloaded, (), (ref(&&), override));202203private:204MockFoo(const MockFoo&) = delete;205MockFoo& operator=(const MockFoo&) = delete;206};207208class LegacyMockFoo : public FooInterface {209public:210LegacyMockFoo() = default;211212// Makes sure that a mock function parameter can be named.213MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT214215MOCK_METHOD0(Nullary, int()); // NOLINT216217// Makes sure that a mock function parameter can be unnamed.218MOCK_METHOD1(Unary, bool(int)); // NOLINT219MOCK_METHOD2(Binary, long(short, int)); // NOLINT220MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float, // NOLINT221double, unsigned, char*, const std::string& str));222223MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT224MOCK_METHOD1(TakesConstReference, std::string(const int&));225MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT226227// Tests that the function return type can contain unprotected comma.228MOCK_METHOD0(ReturnTypeWithComma, std::map<int, std::string>());229MOCK_CONST_METHOD1(ReturnTypeWithComma,230std::map<int, std::string>(int)); // NOLINT231232MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT233MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT234235MOCK_METHOD1(OverloadedOnArgumentType, int(int)); // NOLINT236MOCK_METHOD1(OverloadedOnArgumentType, char(char)); // NOLINT237238MOCK_METHOD0(OverloadedOnConstness, int()); // NOLINT239MOCK_CONST_METHOD0(OverloadedOnConstness, char()); // NOLINT240241MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT242MOCK_METHOD1(TypeWithComma,243int(const std::map<int, std::string>&)); // NOLINT244MOCK_METHOD1(TypeWithTemplatedCopyCtor,245int(const TemplatedCopyable<int>&)); // NOLINT246247MOCK_METHOD1(ReturnsFunctionPointer1, int (*(int))(bool));248MOCK_METHOD1(ReturnsFunctionPointer2, fn_ptr(int));249250#ifdef GTEST_OS_WINDOWS251MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());252MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); // NOLINT253MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal,254int(bool b, char c, short d, int e, // NOLINT255long f, float g, double h, // NOLINT256unsigned i, char* j, const std::string& k));257MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst,258char(int)); // NOLINT259260// Tests that the function return type can contain unprotected comma.261MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTReturnTypeWithComma,262std::map<int, std::string>());263#endif // GTEST_OS_WINDOWS264265// We can't mock these with the old macros, but we need to define them to make266// it concrete.267int RefQualifiedConstRef() const& override { return 0; }268int RefQualifiedConstRefRef() const&& override { return 0; }269int RefQualifiedRef() & override { return 0; }270int RefQualifiedRefRef() && override { return 0; }271int RefQualifiedOverloaded() const& override { return 0; }272int RefQualifiedOverloaded() const&& override { return 0; }273int RefQualifiedOverloaded() & override { return 0; }274int RefQualifiedOverloaded() && override { return 0; }275276private:277LegacyMockFoo(const LegacyMockFoo&) = delete;278LegacyMockFoo& operator=(const LegacyMockFoo&) = delete;279};280281GTEST_DISABLE_MSC_WARNINGS_POP_() // 4373282283template <class T>284class FunctionMockerTest : public testing::Test {285protected:286FunctionMockerTest() : foo_(&mock_foo_) {}287288FooInterface* const foo_;289T mock_foo_;290};291using FunctionMockerTestTypes = ::testing::Types<MockFoo, LegacyMockFoo>;292TYPED_TEST_SUITE(FunctionMockerTest, FunctionMockerTestTypes);293294// Tests mocking a void-returning function.295TYPED_TEST(FunctionMockerTest, MocksVoidFunction) {296EXPECT_CALL(this->mock_foo_, VoidReturning(Lt(100)));297this->foo_->VoidReturning(0);298}299300// Tests mocking a nullary function.301TYPED_TEST(FunctionMockerTest, MocksNullaryFunction) {302EXPECT_CALL(this->mock_foo_, Nullary())303.WillOnce(DoDefault())304.WillOnce(Return(1));305306EXPECT_EQ(0, this->foo_->Nullary());307EXPECT_EQ(1, this->foo_->Nullary());308}309310// Tests mocking a unary function.311TYPED_TEST(FunctionMockerTest, MocksUnaryFunction) {312EXPECT_CALL(this->mock_foo_, Unary(Eq(2))).Times(2).WillOnce(Return(true));313314EXPECT_TRUE(this->foo_->Unary(2));315EXPECT_FALSE(this->foo_->Unary(2));316}317318// Tests mocking a binary function.319TYPED_TEST(FunctionMockerTest, MocksBinaryFunction) {320EXPECT_CALL(this->mock_foo_, Binary(2, _)).WillOnce(Return(3));321322EXPECT_EQ(3, this->foo_->Binary(2, 1));323}324325// Tests mocking a decimal function.326TYPED_TEST(FunctionMockerTest, MocksDecimalFunction) {327EXPECT_CALL(this->mock_foo_,328Decimal(true, 'a', 0, 0, 1L, A<float>(), Lt(100), 5U, NULL, "hi"))329.WillOnce(Return(5));330331EXPECT_EQ(5, this->foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi"));332}333334// Tests mocking a function that takes a non-const reference.335TYPED_TEST(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) {336int a = 0;337EXPECT_CALL(this->mock_foo_, TakesNonConstReference(Ref(a)))338.WillOnce(Return(true));339340EXPECT_TRUE(this->foo_->TakesNonConstReference(a));341}342343// Tests mocking a function that takes a const reference.344TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) {345int a = 0;346EXPECT_CALL(this->mock_foo_, TakesConstReference(Ref(a)))347.WillOnce(Return("Hello"));348349EXPECT_EQ("Hello", this->foo_->TakesConstReference(a));350}351352// Tests mocking a function that takes a const variable.353TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstArgument) {354EXPECT_CALL(this->mock_foo_, TakesConst(Lt(10))).WillOnce(DoDefault());355356EXPECT_FALSE(this->foo_->TakesConst(5));357}358359// Tests mocking functions overloaded on the number of arguments.360TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {361EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber())362.WillOnce(Return(1));363EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber(_))364.WillOnce(Return(2));365366EXPECT_EQ(2, this->foo_->OverloadedOnArgumentNumber(1));367EXPECT_EQ(1, this->foo_->OverloadedOnArgumentNumber());368}369370// Tests mocking functions overloaded on the types of argument.371TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {372EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(An<int>()))373.WillOnce(Return(1));374EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))375.WillOnce(Return('b'));376377EXPECT_EQ(1, this->foo_->OverloadedOnArgumentType(0));378EXPECT_EQ('b', this->foo_->OverloadedOnArgumentType('a'));379}380381// Tests mocking functions overloaded on the const-ness of this object.382TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) {383EXPECT_CALL(this->mock_foo_, OverloadedOnConstness());384EXPECT_CALL(Const(this->mock_foo_), OverloadedOnConstness())385.WillOnce(Return('a'));386387EXPECT_EQ(0, this->foo_->OverloadedOnConstness());388EXPECT_EQ('a', Const(*this->foo_).OverloadedOnConstness());389}390391TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithComma) {392const std::map<int, std::string> a_map;393EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma()).WillOnce(Return(a_map));394EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma(42)).WillOnce(Return(a_map));395396EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma());397EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma(42));398}399400TYPED_TEST(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) {401EXPECT_CALL(this->mock_foo_, TypeWithTemplatedCopyCtor(_))402.WillOnce(Return(true));403EXPECT_TRUE(this->foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>()));404}405406#ifdef GTEST_OS_WINDOWS407// Tests mocking a nullary function with calltype.408TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) {409EXPECT_CALL(this->mock_foo_, CTNullary())410.WillOnce(Return(-1))411.WillOnce(Return(0));412413EXPECT_EQ(-1, this->foo_->CTNullary());414EXPECT_EQ(0, this->foo_->CTNullary());415}416417// Tests mocking a unary function with calltype.418TYPED_TEST(FunctionMockerTest, MocksUnaryFunctionWithCallType) {419EXPECT_CALL(this->mock_foo_, CTUnary(Eq(2)))420.Times(2)421.WillOnce(Return(true))422.WillOnce(Return(false));423424EXPECT_TRUE(this->foo_->CTUnary(2));425EXPECT_FALSE(this->foo_->CTUnary(2));426}427428// Tests mocking a decimal function with calltype.429TYPED_TEST(FunctionMockerTest, MocksDecimalFunctionWithCallType) {430EXPECT_CALL(this->mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(),431Lt(100), 5U, NULL, "hi"))432.WillOnce(Return(10));433434EXPECT_EQ(10, this->foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));435}436437// Tests mocking functions overloaded on the const-ness of this object.438TYPED_TEST(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {439EXPECT_CALL(Const(this->mock_foo_), CTConst(_)).WillOnce(Return('a'));440441EXPECT_EQ('a', Const(*this->foo_).CTConst(0));442}443444TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {445const std::map<int, std::string> a_map;446EXPECT_CALL(this->mock_foo_, CTReturnTypeWithComma()).WillOnce(Return(a_map));447448EXPECT_EQ(a_map, this->mock_foo_.CTReturnTypeWithComma());449}450451#endif // GTEST_OS_WINDOWS452453TEST(FunctionMockerTest, RefQualified) {454MockFoo mock_foo;455456EXPECT_CALL(mock_foo, RefQualifiedConstRef).WillOnce(Return(1));457EXPECT_CALL(std::move(mock_foo), // NOLINT458RefQualifiedConstRefRef)459.WillOnce(Return(2));460EXPECT_CALL(mock_foo, RefQualifiedRef).WillOnce(Return(3));461EXPECT_CALL(std::move(mock_foo), // NOLINT462RefQualifiedRefRef)463.WillOnce(Return(4));464465EXPECT_CALL(static_cast<const MockFoo&>(mock_foo), RefQualifiedOverloaded())466.WillOnce(Return(5));467EXPECT_CALL(static_cast<const MockFoo&&>(mock_foo), RefQualifiedOverloaded())468.WillOnce(Return(6));469EXPECT_CALL(static_cast<MockFoo&>(mock_foo), RefQualifiedOverloaded())470.WillOnce(Return(7));471EXPECT_CALL(static_cast<MockFoo&&>(mock_foo), RefQualifiedOverloaded())472.WillOnce(Return(8));473474EXPECT_EQ(mock_foo.RefQualifiedConstRef(), 1);475EXPECT_EQ(std::move(mock_foo).RefQualifiedConstRefRef(), 2); // NOLINT476EXPECT_EQ(mock_foo.RefQualifiedRef(), 3);477EXPECT_EQ(std::move(mock_foo).RefQualifiedRefRef(), 4); // NOLINT478479EXPECT_EQ(std::cref(mock_foo).get().RefQualifiedOverloaded(), 5);480EXPECT_EQ(std::move(std::cref(mock_foo).get()) // NOLINT481.RefQualifiedOverloaded(),4826);483EXPECT_EQ(mock_foo.RefQualifiedOverloaded(), 7);484EXPECT_EQ(std::move(mock_foo).RefQualifiedOverloaded(), 8); // NOLINT485}486487class MockB {488public:489MockB() = default;490491MOCK_METHOD(void, DoB, ());492493private:494MockB(const MockB&) = delete;495MockB& operator=(const MockB&) = delete;496};497498class LegacyMockB {499public:500LegacyMockB() = default;501502MOCK_METHOD0(DoB, void());503504private:505LegacyMockB(const LegacyMockB&) = delete;506LegacyMockB& operator=(const LegacyMockB&) = delete;507};508509template <typename T>510class ExpectCallTest : public ::testing::Test {};511using ExpectCallTestTypes = ::testing::Types<MockB, LegacyMockB>;512TYPED_TEST_SUITE(ExpectCallTest, ExpectCallTestTypes);513514// Tests that functions with no EXPECT_CALL() rules can be called any515// number of times.516TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {517{ TypeParam b; }518519{520TypeParam b;521b.DoB();522}523524{525TypeParam b;526b.DoB();527b.DoB();528}529}530531// Tests mocking template interfaces.532533template <typename T>534class StackInterface {535public:536virtual ~StackInterface() = default;537538// Template parameter appears in function parameter.539virtual void Push(const T& value) = 0;540virtual void Pop() = 0;541virtual int GetSize() const = 0;542// Template parameter appears in function return type.543virtual const T& GetTop() const = 0;544};545546template <typename T>547class MockStack : public StackInterface<T> {548public:549MockStack() = default;550551MOCK_METHOD(void, Push, (const T& elem), ());552MOCK_METHOD(void, Pop, (), (final));553MOCK_METHOD(int, GetSize, (), (const, override));554MOCK_METHOD(const T&, GetTop, (), (const));555556// Tests that the function return type can contain unprotected comma.557MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (), ());558MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (int), (const));559560private:561MockStack(const MockStack&) = delete;562MockStack& operator=(const MockStack&) = delete;563};564565template <typename T>566class LegacyMockStack : public StackInterface<T> {567public:568LegacyMockStack() = default;569570MOCK_METHOD1_T(Push, void(const T& elem));571MOCK_METHOD0_T(Pop, void());572MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT573MOCK_CONST_METHOD0_T(GetTop, const T&());574575// Tests that the function return type can contain unprotected comma.576MOCK_METHOD0_T(ReturnTypeWithComma, std::map<int, int>());577MOCK_CONST_METHOD1_T(ReturnTypeWithComma, std::map<int, int>(int)); // NOLINT578579private:580LegacyMockStack(const LegacyMockStack&) = delete;581LegacyMockStack& operator=(const LegacyMockStack&) = delete;582};583584template <typename T>585class TemplateMockTest : public ::testing::Test {};586using TemplateMockTestTypes =587::testing::Types<MockStack<int>, LegacyMockStack<int>>;588TYPED_TEST_SUITE(TemplateMockTest, TemplateMockTestTypes);589590// Tests that template mock works.591TYPED_TEST(TemplateMockTest, Works) {592TypeParam mock;593594EXPECT_CALL(mock, GetSize())595.WillOnce(Return(0))596.WillOnce(Return(1))597.WillOnce(Return(0));598EXPECT_CALL(mock, Push(_));599int n = 5;600EXPECT_CALL(mock, GetTop()).WillOnce(ReturnRef(n));601EXPECT_CALL(mock, Pop()).Times(AnyNumber());602603EXPECT_EQ(0, mock.GetSize());604mock.Push(5);605EXPECT_EQ(1, mock.GetSize());606EXPECT_EQ(5, mock.GetTop());607mock.Pop();608EXPECT_EQ(0, mock.GetSize());609}610611TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {612TypeParam mock;613614const std::map<int, int> a_map;615EXPECT_CALL(mock, ReturnTypeWithComma()).WillOnce(Return(a_map));616EXPECT_CALL(mock, ReturnTypeWithComma(1)).WillOnce(Return(a_map));617618EXPECT_EQ(a_map, mock.ReturnTypeWithComma());619EXPECT_EQ(a_map, mock.ReturnTypeWithComma(1));620}621622#ifdef GTEST_OS_WINDOWS623// Tests mocking template interfaces with calltype.624625template <typename T>626class StackInterfaceWithCallType {627public:628virtual ~StackInterfaceWithCallType() {}629630// Template parameter appears in function parameter.631STDMETHOD_(void, Push)(const T& value) = 0;632STDMETHOD_(void, Pop)() = 0;633STDMETHOD_(int, GetSize)() const = 0;634// Template parameter appears in function return type.635STDMETHOD_(const T&, GetTop)() const = 0;636};637638template <typename T>639class MockStackWithCallType : public StackInterfaceWithCallType<T> {640public:641MockStackWithCallType() {}642643MOCK_METHOD(void, Push, (const T& elem),644(Calltype(STDMETHODCALLTYPE), override));645MOCK_METHOD(void, Pop, (), (Calltype(STDMETHODCALLTYPE), override));646MOCK_METHOD(int, GetSize, (), (Calltype(STDMETHODCALLTYPE), override, const));647MOCK_METHOD(const T&, GetTop, (),648(Calltype(STDMETHODCALLTYPE), override, const));649650private:651MockStackWithCallType(const MockStackWithCallType&) = delete;652MockStackWithCallType& operator=(const MockStackWithCallType&) = delete;653};654655template <typename T>656class LegacyMockStackWithCallType : public StackInterfaceWithCallType<T> {657public:658LegacyMockStackWithCallType() {}659660MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem));661MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void());662MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int());663MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&());664665private:666LegacyMockStackWithCallType(const LegacyMockStackWithCallType&) = delete;667LegacyMockStackWithCallType& operator=(const LegacyMockStackWithCallType&) =668delete;669};670671template <typename T>672class TemplateMockTestWithCallType : public ::testing::Test {};673using TemplateMockTestWithCallTypeTypes =674::testing::Types<MockStackWithCallType<int>,675LegacyMockStackWithCallType<int>>;676TYPED_TEST_SUITE(TemplateMockTestWithCallType,677TemplateMockTestWithCallTypeTypes);678679// Tests that template mock with calltype works.680TYPED_TEST(TemplateMockTestWithCallType, Works) {681TypeParam mock;682683EXPECT_CALL(mock, GetSize())684.WillOnce(Return(0))685.WillOnce(Return(1))686.WillOnce(Return(0));687EXPECT_CALL(mock, Push(_));688int n = 5;689EXPECT_CALL(mock, GetTop()).WillOnce(ReturnRef(n));690EXPECT_CALL(mock, Pop()).Times(AnyNumber());691692EXPECT_EQ(0, mock.GetSize());693mock.Push(5);694EXPECT_EQ(1, mock.GetSize());695EXPECT_EQ(5, mock.GetTop());696mock.Pop();697EXPECT_EQ(0, mock.GetSize());698}699#endif // GTEST_OS_WINDOWS700701#define MY_MOCK_METHODS1_ \702MOCK_METHOD(void, Overloaded, ()); \703MOCK_METHOD(int, Overloaded, (int), (const)); \704MOCK_METHOD(bool, Overloaded, (bool f, int n))705706#define LEGACY_MY_MOCK_METHODS1_ \707MOCK_METHOD0(Overloaded, void()); \708MOCK_CONST_METHOD1(Overloaded, int(int n)); \709MOCK_METHOD2(Overloaded, bool(bool f, int n))710711class MockOverloadedOnArgNumber {712public:713MockOverloadedOnArgNumber() = default;714715MY_MOCK_METHODS1_;716717private:718MockOverloadedOnArgNumber(const MockOverloadedOnArgNumber&) = delete;719MockOverloadedOnArgNumber& operator=(const MockOverloadedOnArgNumber&) =720delete;721};722723class LegacyMockOverloadedOnArgNumber {724public:725LegacyMockOverloadedOnArgNumber() = default;726727LEGACY_MY_MOCK_METHODS1_;728729private:730LegacyMockOverloadedOnArgNumber(const LegacyMockOverloadedOnArgNumber&) =731delete;732LegacyMockOverloadedOnArgNumber& operator=(733const LegacyMockOverloadedOnArgNumber&) = delete;734};735736template <typename T>737class OverloadedMockMethodTest : public ::testing::Test {};738using OverloadedMockMethodTestTypes =739::testing::Types<MockOverloadedOnArgNumber,740LegacyMockOverloadedOnArgNumber>;741TYPED_TEST_SUITE(OverloadedMockMethodTest, OverloadedMockMethodTestTypes);742743TYPED_TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) {744TypeParam mock;745EXPECT_CALL(mock, Overloaded());746EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));747EXPECT_CALL(mock, Overloaded(true, 1)).WillOnce(Return(true));748749mock.Overloaded();750EXPECT_EQ(2, mock.Overloaded(1));751EXPECT_TRUE(mock.Overloaded(true, 1));752}753754#define MY_MOCK_METHODS2_ \755MOCK_CONST_METHOD1(Overloaded, int(int n)); \756MOCK_METHOD1(Overloaded, int(int n))757758class MockOverloadedOnConstness {759public:760MockOverloadedOnConstness() = default;761762MY_MOCK_METHODS2_;763764private:765MockOverloadedOnConstness(const MockOverloadedOnConstness&) = delete;766MockOverloadedOnConstness& operator=(const MockOverloadedOnConstness&) =767delete;768};769770TEST(MockMethodOverloadedMockMethodTest, CanOverloadOnConstnessInMacroBody) {771MockOverloadedOnConstness mock;772const MockOverloadedOnConstness* const_mock = &mock;773EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));774EXPECT_CALL(*const_mock, Overloaded(1)).WillOnce(Return(3));775776EXPECT_EQ(2, mock.Overloaded(1));777EXPECT_EQ(3, const_mock->Overloaded(1));778}779780TEST(MockMethodMockFunctionTest, WorksForVoidNullary) {781MockFunction<void()> foo;782EXPECT_CALL(foo, Call());783foo.Call();784}785786TEST(MockMethodMockFunctionTest, WorksForNonVoidNullary) {787MockFunction<int()> foo;788EXPECT_CALL(foo, Call()).WillOnce(Return(1)).WillOnce(Return(2));789EXPECT_EQ(1, foo.Call());790EXPECT_EQ(2, foo.Call());791}792793TEST(MockMethodMockFunctionTest, WorksForVoidUnary) {794MockFunction<void(int)> foo;795EXPECT_CALL(foo, Call(1));796foo.Call(1);797}798799TEST(MockMethodMockFunctionTest, WorksForNonVoidBinary) {800MockFunction<int(bool, int)> foo;801EXPECT_CALL(foo, Call(false, 42)).WillOnce(Return(1)).WillOnce(Return(2));802EXPECT_CALL(foo, Call(true, Ge(100))).WillOnce(Return(3));803EXPECT_EQ(1, foo.Call(false, 42));804EXPECT_EQ(2, foo.Call(false, 42));805EXPECT_EQ(3, foo.Call(true, 120));806}807808TEST(MockMethodMockFunctionTest, WorksFor10Arguments) {809MockFunction<int(bool a0, char a1, int a2, int a3, int a4, int a5, int a6,810char a7, int a8, bool a9)>811foo;812EXPECT_CALL(foo, Call(_, 'a', _, _, _, _, _, _, _, _))813.WillOnce(Return(1))814.WillOnce(Return(2));815EXPECT_EQ(1, foo.Call(false, 'a', 0, 0, 0, 0, 0, 'b', 0, true));816EXPECT_EQ(2, foo.Call(true, 'a', 0, 0, 0, 0, 0, 'b', 1, false));817}818819TEST(MockMethodMockFunctionTest, AsStdFunction) {820MockFunction<int(int)> foo;821auto call = [](const std::function<int(int)>& f, int i) { return f(i); };822EXPECT_CALL(foo, Call(1)).WillOnce(Return(-1));823EXPECT_CALL(foo, Call(2)).WillOnce(Return(-2));824EXPECT_EQ(-1, call(foo.AsStdFunction(), 1));825EXPECT_EQ(-2, call(foo.AsStdFunction(), 2));826}827828TEST(MockMethodMockFunctionTest, AsStdFunctionReturnsReference) {829MockFunction<int&()> foo;830int value = 1;831EXPECT_CALL(foo, Call()).WillOnce(ReturnRef(value));832int& ref = foo.AsStdFunction()();833EXPECT_EQ(1, ref);834value = 2;835EXPECT_EQ(2, ref);836}837838TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) {839MockFunction<int(int&)> foo;840auto call = [](const std::function<int(int&)>& f, int& i) { return f(i); };841int i = 42;842EXPECT_CALL(foo, Call(i)).WillOnce(Return(-1));843EXPECT_EQ(-1, call(foo.AsStdFunction(), i));844}845846namespace {847848template <typename Expected, typename F>849static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(850const internal::MockFunction<F>&) {851return std::is_same<F, Expected>::value;852}853854} // namespace855856template <typename F>857class MockMethodMockFunctionSignatureTest : public Test {};858859using MockMethodMockFunctionSignatureTypes =860Types<void(), int(), void(int), int(int), int(bool, int),861int(bool, char, int, int, int, int, int, char, int, bool)>;862TYPED_TEST_SUITE(MockMethodMockFunctionSignatureTest,863MockMethodMockFunctionSignatureTypes);864865TYPED_TEST(MockMethodMockFunctionSignatureTest,866IsMockFunctionTemplateArgumentDeducedForRawSignature) {867using Argument = TypeParam;868MockFunction<Argument> foo;869EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));870}871872TYPED_TEST(MockMethodMockFunctionSignatureTest,873IsMockFunctionTemplateArgumentDeducedForStdFunction) {874using Argument = std::function<TypeParam>;875MockFunction<Argument> foo;876EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));877}878879TYPED_TEST(880MockMethodMockFunctionSignatureTest,881IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) {882using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);883using ForStdFunction =884decltype(&MockFunction<std::function<TypeParam>>::Call);885EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));886}887888template <typename F>889struct AlternateCallable {};890891TYPED_TEST(MockMethodMockFunctionSignatureTest,892IsMockFunctionTemplateArgumentDeducedForAlternateCallable) {893using Argument = AlternateCallable<TypeParam>;894MockFunction<Argument> foo;895EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<TypeParam>(foo));896}897898TYPED_TEST(MockMethodMockFunctionSignatureTest,899IsMockFunctionCallMethodSignatureTheSameForAlternateCallable) {900using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);901using ForStdFunction =902decltype(&MockFunction<std::function<TypeParam>>::Call);903EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));904}905906struct MockMethodSizes0 {907MOCK_METHOD(void, func, ());908};909struct MockMethodSizes1 {910MOCK_METHOD(void, func, (int));911};912struct MockMethodSizes2 {913MOCK_METHOD(void, func, (int, int));914};915struct MockMethodSizes3 {916MOCK_METHOD(void, func, (int, int, int));917};918struct MockMethodSizes4 {919MOCK_METHOD(void, func, (int, int, int, int));920};921922struct LegacyMockMethodSizes0 {923MOCK_METHOD0(func, void());924};925struct LegacyMockMethodSizes1 {926MOCK_METHOD1(func, void(int));927};928struct LegacyMockMethodSizes2 {929MOCK_METHOD2(func, void(int, int));930};931struct LegacyMockMethodSizes3 {932MOCK_METHOD3(func, void(int, int, int));933};934struct LegacyMockMethodSizes4 {935MOCK_METHOD4(func, void(int, int, int, int));936};937938TEST(MockMethodMockFunctionTest, MockMethodSizeOverhead) {939EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes1));940EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes2));941EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes3));942EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes4));943944EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes1));945EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes2));946EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes3));947EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes4));948949EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(MockMethodSizes0));950}951952TEST(MockMethodMockFunctionTest, EnsureNoUnusedMemberFunction) {953#ifdef __clang__954#pragma clang diagnostic push955#pragma clang diagnostic error "-Wunused-member-function"956#endif957// https://github.com/google/googletest/issues/4052958struct Foo {959MOCK_METHOD(void, foo, ());960};961EXPECT_CALL(Foo(), foo()).Times(0);962#ifdef __clang__963#pragma clang diagnostic pop964#endif965}966967void hasTwoParams(int, int);968void MaybeThrows();969void DoesntThrow() noexcept;970struct MockMethodNoexceptSpecifier {971MOCK_METHOD(void, func1, (), (noexcept));972MOCK_METHOD(void, func2, (), (noexcept(true)));973MOCK_METHOD(void, func3, (), (noexcept(false)));974MOCK_METHOD(void, func4, (), (noexcept(noexcept(MaybeThrows()))));975MOCK_METHOD(void, func5, (), (noexcept(noexcept(DoesntThrow()))));976MOCK_METHOD(void, func6, (), (noexcept(noexcept(DoesntThrow())), const));977MOCK_METHOD(void, func7, (), (const, noexcept(noexcept(DoesntThrow()))));978// Put commas in the noexcept expression979MOCK_METHOD(void, func8, (), (noexcept(noexcept(hasTwoParams(1, 2))), const));980};981982TEST(MockMethodMockFunctionTest, NoexceptSpecifierPreserved) {983EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func1()));984EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func2()));985EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func3()));986EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func4()));987EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func5()));988EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func6()));989EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func7()));990EXPECT_EQ(noexcept(std::declval<MockMethodNoexceptSpecifier>().func8()),991noexcept(hasTwoParams(1, 2)));992}993994} // namespace gmock_function_mocker_test995} // namespace testing996997GTEST_DISABLE_MSC_WARNINGS_POP_() // 45039989991000