1 // Copyright 2007, 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
31 // Google Mock - a framework for writing C++ mock classes.
32 //
33 // This file tests the function mocker classes.
34 #include "gmock/gmock-function-mocker.h"
35
36 #if GTEST_OS_WINDOWS
37 // MSDN says the header file to be included for STDMETHOD is BaseTyps.h but
38 // we are getting compiler errors if we use basetyps.h, hence including
39 // objbase.h for definition of STDMETHOD.
40 # include <objbase.h>
41 #endif // GTEST_OS_WINDOWS
42
43 #include <functional>
44 #include <map>
45 #include <string>
46 #include <type_traits>
47
48 #include "gmock/gmock.h"
49 #include "gtest/gtest.h"
50
51 namespace testing {
52 namespace gmock_function_mocker_test {
53
54 using testing::_;
55 using testing::A;
56 using testing::An;
57 using testing::AnyNumber;
58 using testing::Const;
59 using testing::DoDefault;
60 using testing::Eq;
61 using testing::Lt;
62 using testing::MockFunction;
63 using testing::Ref;
64 using testing::Return;
65 using testing::ReturnRef;
66 using testing::TypedEq;
67
68 template<typename T>
69 class TemplatedCopyable {
70 public:
TemplatedCopyable()71 TemplatedCopyable() {}
72
73 template <typename U>
TemplatedCopyable(const U & other)74 TemplatedCopyable(const U& other) {} // NOLINT
75 };
76
77 class FooInterface {
78 public:
~FooInterface()79 virtual ~FooInterface() {}
80
81 virtual void VoidReturning(int x) = 0;
82
83 virtual int Nullary() = 0;
84 virtual bool Unary(int x) = 0;
85 virtual long Binary(short x, int y) = 0; // NOLINT
86 virtual int Decimal(bool b, char c, short d, int e, long f, // NOLINT
87 float g, double h, unsigned i, char* j,
88 const std::string& k) = 0;
89
90 virtual bool TakesNonConstReference(int& n) = 0; // NOLINT
91 virtual std::string TakesConstReference(const int& n) = 0;
92 virtual bool TakesConst(const int x) = 0;
93
94 virtual int OverloadedOnArgumentNumber() = 0;
95 virtual int OverloadedOnArgumentNumber(int n) = 0;
96
97 virtual int OverloadedOnArgumentType(int n) = 0;
98 virtual char OverloadedOnArgumentType(char c) = 0;
99
100 virtual int OverloadedOnConstness() = 0;
101 virtual char OverloadedOnConstness() const = 0;
102
103 virtual int TypeWithHole(int (*func)()) = 0;
104 virtual int TypeWithComma(const std::map<int, std::string>& a_map) = 0;
105 virtual int TypeWithTemplatedCopyCtor(const TemplatedCopyable<int>&) = 0;
106
107 virtual int (*ReturnsFunctionPointer1(int))(bool) = 0;
108 using fn_ptr = int (*)(bool);
109 virtual fn_ptr ReturnsFunctionPointer2(int) = 0;
110
111 #if GTEST_OS_WINDOWS
112 STDMETHOD_(int, CTNullary)() = 0;
113 STDMETHOD_(bool, CTUnary)(int x) = 0;
114 STDMETHOD_(int, CTDecimal)
115 (bool b, char c, short d, int e, long f, // NOLINT
116 float g, double h, unsigned i, char* j, const std::string& k) = 0;
117 STDMETHOD_(char, CTConst)(int x) const = 0;
118 #endif // GTEST_OS_WINDOWS
119 };
120
121 // Const qualifiers on arguments were once (incorrectly) considered
122 // significant in determining whether two virtual functions had the same
123 // signature. This was fixed in Visual Studio 2008. However, the compiler
124 // still emits a warning that alerts about this change in behavior.
125 #ifdef _MSC_VER
126 # pragma warning(push)
127 # pragma warning(disable : 4373)
128 #endif
129 class MockFoo : public FooInterface {
130 public:
MockFoo()131 MockFoo() {}
132
133 // Makes sure that a mock function parameter can be named.
134 MOCK_METHOD(void, VoidReturning, (int n)); // NOLINT
135
136 MOCK_METHOD(int, Nullary, ()); // NOLINT
137
138 // Makes sure that a mock function parameter can be unnamed.
139 MOCK_METHOD(bool, Unary, (int)); // NOLINT
140 MOCK_METHOD(long, Binary, (short, int)); // NOLINT
141 MOCK_METHOD(int, Decimal,
142 (bool, char, short, int, long, float, // NOLINT
143 double, unsigned, char*, const std::string& str),
144 (override));
145
146 MOCK_METHOD(bool, TakesNonConstReference, (int&)); // NOLINT
147 MOCK_METHOD(std::string, TakesConstReference, (const int&));
148 MOCK_METHOD(bool, TakesConst, (const int)); // NOLINT
149
150 // Tests that the function return type can contain unprotected comma.
151 MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (), ());
152 MOCK_METHOD((std::map<int, std::string>), ReturnTypeWithComma, (int),
153 (const)); // NOLINT
154
155 MOCK_METHOD(int, OverloadedOnArgumentNumber, ()); // NOLINT
156 MOCK_METHOD(int, OverloadedOnArgumentNumber, (int)); // NOLINT
157
158 MOCK_METHOD(int, OverloadedOnArgumentType, (int)); // NOLINT
159 MOCK_METHOD(char, OverloadedOnArgumentType, (char)); // NOLINT
160
161 MOCK_METHOD(int, OverloadedOnConstness, (), (override)); // NOLINT
162 MOCK_METHOD(char, OverloadedOnConstness, (), (override, const)); // NOLINT
163
164 MOCK_METHOD(int, TypeWithHole, (int (*)()), ()); // NOLINT
165 MOCK_METHOD(int, TypeWithComma, ((const std::map<int, std::string>&)));
166 MOCK_METHOD(int, TypeWithTemplatedCopyCtor,
167 (const TemplatedCopyable<int>&)); // NOLINT
168
169 MOCK_METHOD(int (*)(bool), ReturnsFunctionPointer1, (int), ());
170 MOCK_METHOD(fn_ptr, ReturnsFunctionPointer2, (int), ());
171
172 #if GTEST_OS_WINDOWS
173 MOCK_METHOD(int, CTNullary, (), (Calltype(STDMETHODCALLTYPE)));
174 MOCK_METHOD(bool, CTUnary, (int), (Calltype(STDMETHODCALLTYPE)));
175 MOCK_METHOD(int, CTDecimal,
176 (bool b, char c, short d, int e, long f, float g, double h,
177 unsigned i, char* j, const std::string& k),
178 (Calltype(STDMETHODCALLTYPE)));
179 MOCK_METHOD(char, CTConst, (int), (const, Calltype(STDMETHODCALLTYPE)));
180 MOCK_METHOD((std::map<int, std::string>), CTReturnTypeWithComma, (),
181 (Calltype(STDMETHODCALLTYPE)));
182 #endif // GTEST_OS_WINDOWS
183
184 private:
185 GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
186 };
187
188 class LegacyMockFoo : public FooInterface {
189 public:
LegacyMockFoo()190 LegacyMockFoo() {}
191
192 // Makes sure that a mock function parameter can be named.
193 MOCK_METHOD1(VoidReturning, void(int n)); // NOLINT
194
195 MOCK_METHOD0(Nullary, int()); // NOLINT
196
197 // Makes sure that a mock function parameter can be unnamed.
198 MOCK_METHOD1(Unary, bool(int)); // NOLINT
199 MOCK_METHOD2(Binary, long(short, int)); // NOLINT
200 MOCK_METHOD10(Decimal, int(bool, char, short, int, long, float, // NOLINT
201 double, unsigned, char*, const std::string& str));
202
203 MOCK_METHOD1(TakesNonConstReference, bool(int&)); // NOLINT
204 MOCK_METHOD1(TakesConstReference, std::string(const int&));
205 MOCK_METHOD1(TakesConst, bool(const int)); // NOLINT
206
207 // Tests that the function return type can contain unprotected comma.
208 MOCK_METHOD0(ReturnTypeWithComma, std::map<int, std::string>());
209 MOCK_CONST_METHOD1(ReturnTypeWithComma,
210 std::map<int, std::string>(int)); // NOLINT
211
212 MOCK_METHOD0(OverloadedOnArgumentNumber, int()); // NOLINT
213 MOCK_METHOD1(OverloadedOnArgumentNumber, int(int)); // NOLINT
214
215 MOCK_METHOD1(OverloadedOnArgumentType, int(int)); // NOLINT
216 MOCK_METHOD1(OverloadedOnArgumentType, char(char)); // NOLINT
217
218 MOCK_METHOD0(OverloadedOnConstness, int()); // NOLINT
219 MOCK_CONST_METHOD0(OverloadedOnConstness, char()); // NOLINT
220
221 MOCK_METHOD1(TypeWithHole, int(int (*)())); // NOLINT
222 MOCK_METHOD1(TypeWithComma,
223 int(const std::map<int, std::string>&)); // NOLINT
224 MOCK_METHOD1(TypeWithTemplatedCopyCtor,
225 int(const TemplatedCopyable<int>&)); // NOLINT
226
227 MOCK_METHOD1(ReturnsFunctionPointer1, int (*(int))(bool));
228 MOCK_METHOD1(ReturnsFunctionPointer2, fn_ptr(int));
229
230 #if GTEST_OS_WINDOWS
231 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTNullary, int());
232 MOCK_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTUnary, bool(int)); // NOLINT
233 MOCK_METHOD10_WITH_CALLTYPE(STDMETHODCALLTYPE, CTDecimal,
234 int(bool b, char c, short d, int e, // NOLINT
235 long f, float g, double h, // NOLINT
236 unsigned i, char* j, const std::string& k));
237 MOCK_CONST_METHOD1_WITH_CALLTYPE(STDMETHODCALLTYPE, CTConst,
238 char(int)); // NOLINT
239
240 // Tests that the function return type can contain unprotected comma.
241 MOCK_METHOD0_WITH_CALLTYPE(STDMETHODCALLTYPE, CTReturnTypeWithComma,
242 std::map<int, std::string>());
243 #endif // GTEST_OS_WINDOWS
244
245 private:
246 GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockFoo);
247 };
248
249 #ifdef _MSC_VER
250 # pragma warning(pop)
251 #endif
252
253 template <class T>
254 class FunctionMockerTest : public testing::Test {
255 protected:
FunctionMockerTest()256 FunctionMockerTest() : foo_(&mock_foo_) {}
257
258 FooInterface* const foo_;
259 T mock_foo_;
260 };
261 using FunctionMockerTestTypes = ::testing::Types<MockFoo, LegacyMockFoo>;
262 TYPED_TEST_SUITE(FunctionMockerTest, FunctionMockerTestTypes);
263
264 // Tests mocking a void-returning function.
TYPED_TEST(FunctionMockerTest,MocksVoidFunction)265 TYPED_TEST(FunctionMockerTest, MocksVoidFunction) {
266 EXPECT_CALL(this->mock_foo_, VoidReturning(Lt(100)));
267 this->foo_->VoidReturning(0);
268 }
269
270 // Tests mocking a nullary function.
TYPED_TEST(FunctionMockerTest,MocksNullaryFunction)271 TYPED_TEST(FunctionMockerTest, MocksNullaryFunction) {
272 EXPECT_CALL(this->mock_foo_, Nullary())
273 .WillOnce(DoDefault())
274 .WillOnce(Return(1));
275
276 EXPECT_EQ(0, this->foo_->Nullary());
277 EXPECT_EQ(1, this->foo_->Nullary());
278 }
279
280 // Tests mocking a unary function.
TYPED_TEST(FunctionMockerTest,MocksUnaryFunction)281 TYPED_TEST(FunctionMockerTest, MocksUnaryFunction) {
282 EXPECT_CALL(this->mock_foo_, Unary(Eq(2))).Times(2).WillOnce(Return(true));
283
284 EXPECT_TRUE(this->foo_->Unary(2));
285 EXPECT_FALSE(this->foo_->Unary(2));
286 }
287
288 // Tests mocking a binary function.
TYPED_TEST(FunctionMockerTest,MocksBinaryFunction)289 TYPED_TEST(FunctionMockerTest, MocksBinaryFunction) {
290 EXPECT_CALL(this->mock_foo_, Binary(2, _)).WillOnce(Return(3));
291
292 EXPECT_EQ(3, this->foo_->Binary(2, 1));
293 }
294
295 // Tests mocking a decimal function.
TYPED_TEST(FunctionMockerTest,MocksDecimalFunction)296 TYPED_TEST(FunctionMockerTest, MocksDecimalFunction) {
297 EXPECT_CALL(this->mock_foo_,
298 Decimal(true, 'a', 0, 0, 1L, A<float>(), Lt(100), 5U, NULL, "hi"))
299 .WillOnce(Return(5));
300
301 EXPECT_EQ(5, this->foo_->Decimal(true, 'a', 0, 0, 1, 0, 0, 5, nullptr, "hi"));
302 }
303
304 // Tests mocking a function that takes a non-const reference.
TYPED_TEST(FunctionMockerTest,MocksFunctionWithNonConstReferenceArgument)305 TYPED_TEST(FunctionMockerTest, MocksFunctionWithNonConstReferenceArgument) {
306 int a = 0;
307 EXPECT_CALL(this->mock_foo_, TakesNonConstReference(Ref(a)))
308 .WillOnce(Return(true));
309
310 EXPECT_TRUE(this->foo_->TakesNonConstReference(a));
311 }
312
313 // Tests mocking a function that takes a const reference.
TYPED_TEST(FunctionMockerTest,MocksFunctionWithConstReferenceArgument)314 TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstReferenceArgument) {
315 int a = 0;
316 EXPECT_CALL(this->mock_foo_, TakesConstReference(Ref(a)))
317 .WillOnce(Return("Hello"));
318
319 EXPECT_EQ("Hello", this->foo_->TakesConstReference(a));
320 }
321
322 // Tests mocking a function that takes a const variable.
TYPED_TEST(FunctionMockerTest,MocksFunctionWithConstArgument)323 TYPED_TEST(FunctionMockerTest, MocksFunctionWithConstArgument) {
324 EXPECT_CALL(this->mock_foo_, TakesConst(Lt(10))).WillOnce(DoDefault());
325
326 EXPECT_FALSE(this->foo_->TakesConst(5));
327 }
328
329 // Tests mocking functions overloaded on the number of arguments.
TYPED_TEST(FunctionMockerTest,MocksFunctionsOverloadedOnArgumentNumber)330 TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentNumber) {
331 EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber())
332 .WillOnce(Return(1));
333 EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentNumber(_))
334 .WillOnce(Return(2));
335
336 EXPECT_EQ(2, this->foo_->OverloadedOnArgumentNumber(1));
337 EXPECT_EQ(1, this->foo_->OverloadedOnArgumentNumber());
338 }
339
340 // Tests mocking functions overloaded on the types of argument.
TYPED_TEST(FunctionMockerTest,MocksFunctionsOverloadedOnArgumentType)341 TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnArgumentType) {
342 EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(An<int>()))
343 .WillOnce(Return(1));
344 EXPECT_CALL(this->mock_foo_, OverloadedOnArgumentType(TypedEq<char>('a')))
345 .WillOnce(Return('b'));
346
347 EXPECT_EQ(1, this->foo_->OverloadedOnArgumentType(0));
348 EXPECT_EQ('b', this->foo_->OverloadedOnArgumentType('a'));
349 }
350
351 // Tests mocking functions overloaded on the const-ness of this object.
TYPED_TEST(FunctionMockerTest,MocksFunctionsOverloadedOnConstnessOfThis)352 TYPED_TEST(FunctionMockerTest, MocksFunctionsOverloadedOnConstnessOfThis) {
353 EXPECT_CALL(this->mock_foo_, OverloadedOnConstness());
354 EXPECT_CALL(Const(this->mock_foo_), OverloadedOnConstness())
355 .WillOnce(Return('a'));
356
357 EXPECT_EQ(0, this->foo_->OverloadedOnConstness());
358 EXPECT_EQ('a', Const(*this->foo_).OverloadedOnConstness());
359 }
360
TYPED_TEST(FunctionMockerTest,MocksReturnTypeWithComma)361 TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithComma) {
362 const std::map<int, std::string> a_map;
363 EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma()).WillOnce(Return(a_map));
364 EXPECT_CALL(this->mock_foo_, ReturnTypeWithComma(42)).WillOnce(Return(a_map));
365
366 EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma());
367 EXPECT_EQ(a_map, this->mock_foo_.ReturnTypeWithComma(42));
368 }
369
TYPED_TEST(FunctionMockerTest,MocksTypeWithTemplatedCopyCtor)370 TYPED_TEST(FunctionMockerTest, MocksTypeWithTemplatedCopyCtor) {
371 EXPECT_CALL(this->mock_foo_, TypeWithTemplatedCopyCtor(_))
372 .WillOnce(Return(true));
373 EXPECT_TRUE(this->foo_->TypeWithTemplatedCopyCtor(TemplatedCopyable<int>()));
374 }
375
376 #if GTEST_OS_WINDOWS
377 // Tests mocking a nullary function with calltype.
TYPED_TEST(FunctionMockerTest,MocksNullaryFunctionWithCallType)378 TYPED_TEST(FunctionMockerTest, MocksNullaryFunctionWithCallType) {
379 EXPECT_CALL(this->mock_foo_, CTNullary())
380 .WillOnce(Return(-1))
381 .WillOnce(Return(0));
382
383 EXPECT_EQ(-1, this->foo_->CTNullary());
384 EXPECT_EQ(0, this->foo_->CTNullary());
385 }
386
387 // Tests mocking a unary function with calltype.
TYPED_TEST(FunctionMockerTest,MocksUnaryFunctionWithCallType)388 TYPED_TEST(FunctionMockerTest, MocksUnaryFunctionWithCallType) {
389 EXPECT_CALL(this->mock_foo_, CTUnary(Eq(2)))
390 .Times(2)
391 .WillOnce(Return(true))
392 .WillOnce(Return(false));
393
394 EXPECT_TRUE(this->foo_->CTUnary(2));
395 EXPECT_FALSE(this->foo_->CTUnary(2));
396 }
397
398 // Tests mocking a decimal function with calltype.
TYPED_TEST(FunctionMockerTest,MocksDecimalFunctionWithCallType)399 TYPED_TEST(FunctionMockerTest, MocksDecimalFunctionWithCallType) {
400 EXPECT_CALL(this->mock_foo_, CTDecimal(true, 'a', 0, 0, 1L, A<float>(),
401 Lt(100), 5U, NULL, "hi"))
402 .WillOnce(Return(10));
403
404 EXPECT_EQ(10, this->foo_->CTDecimal(true, 'a', 0, 0, 1, 0, 0, 5, NULL, "hi"));
405 }
406
407 // Tests mocking functions overloaded on the const-ness of this object.
TYPED_TEST(FunctionMockerTest,MocksFunctionsConstFunctionWithCallType)408 TYPED_TEST(FunctionMockerTest, MocksFunctionsConstFunctionWithCallType) {
409 EXPECT_CALL(Const(this->mock_foo_), CTConst(_)).WillOnce(Return('a'));
410
411 EXPECT_EQ('a', Const(*this->foo_).CTConst(0));
412 }
413
TYPED_TEST(FunctionMockerTest,MocksReturnTypeWithCommaAndCallType)414 TYPED_TEST(FunctionMockerTest, MocksReturnTypeWithCommaAndCallType) {
415 const std::map<int, std::string> a_map;
416 EXPECT_CALL(this->mock_foo_, CTReturnTypeWithComma()).WillOnce(Return(a_map));
417
418 EXPECT_EQ(a_map, this->mock_foo_.CTReturnTypeWithComma());
419 }
420
421 #endif // GTEST_OS_WINDOWS
422
423 class MockB {
424 public:
MockB()425 MockB() {}
426
427 MOCK_METHOD(void, DoB, ());
428
429 private:
430 GTEST_DISALLOW_COPY_AND_ASSIGN_(MockB);
431 };
432
433 class LegacyMockB {
434 public:
LegacyMockB()435 LegacyMockB() {}
436
437 MOCK_METHOD0(DoB, void());
438
439 private:
440 GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockB);
441 };
442
443 template <typename T>
444 class ExpectCallTest : public ::testing::Test {};
445 using ExpectCallTestTypes = ::testing::Types<MockB, LegacyMockB>;
446 TYPED_TEST_SUITE(ExpectCallTest, ExpectCallTestTypes);
447
448 // Tests that functions with no EXPECT_CALL() rules can be called any
449 // number of times.
TYPED_TEST(ExpectCallTest,UnmentionedFunctionCanBeCalledAnyNumberOfTimes)450 TYPED_TEST(ExpectCallTest, UnmentionedFunctionCanBeCalledAnyNumberOfTimes) {
451 { TypeParam b; }
452
453 {
454 TypeParam b;
455 b.DoB();
456 }
457
458 {
459 TypeParam b;
460 b.DoB();
461 b.DoB();
462 }
463 }
464
465 // Tests mocking template interfaces.
466
467 template <typename T>
468 class StackInterface {
469 public:
~StackInterface()470 virtual ~StackInterface() {}
471
472 // Template parameter appears in function parameter.
473 virtual void Push(const T& value) = 0;
474 virtual void Pop() = 0;
475 virtual int GetSize() const = 0;
476 // Template parameter appears in function return type.
477 virtual const T& GetTop() const = 0;
478 };
479
480 template <typename T>
481 class MockStack : public StackInterface<T> {
482 public:
MockStack()483 MockStack() {}
484
485 MOCK_METHOD(void, Push, (const T& elem), ());
486 MOCK_METHOD(void, Pop, (), (final));
487 MOCK_METHOD(int, GetSize, (), (const, override));
488 MOCK_METHOD(const T&, GetTop, (), (const));
489
490 // Tests that the function return type can contain unprotected comma.
491 MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (), ());
492 MOCK_METHOD((std::map<int, int>), ReturnTypeWithComma, (int), (const));
493
494 private:
495 GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStack);
496 };
497
498 template <typename T>
499 class LegacyMockStack : public StackInterface<T> {
500 public:
LegacyMockStack()501 LegacyMockStack() {}
502
503 MOCK_METHOD1_T(Push, void(const T& elem));
504 MOCK_METHOD0_T(Pop, void());
505 MOCK_CONST_METHOD0_T(GetSize, int()); // NOLINT
506 MOCK_CONST_METHOD0_T(GetTop, const T&());
507
508 // Tests that the function return type can contain unprotected comma.
509 MOCK_METHOD0_T(ReturnTypeWithComma, std::map<int, int>());
510 MOCK_CONST_METHOD1_T(ReturnTypeWithComma, std::map<int, int>(int)); // NOLINT
511
512 private:
513 GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStack);
514 };
515
516 template <typename T>
517 class TemplateMockTest : public ::testing::Test {};
518 using TemplateMockTestTypes =
519 ::testing::Types<MockStack<int>, LegacyMockStack<int>>;
520 TYPED_TEST_SUITE(TemplateMockTest, TemplateMockTestTypes);
521
522 // Tests that template mock works.
TYPED_TEST(TemplateMockTest,Works)523 TYPED_TEST(TemplateMockTest, Works) {
524 TypeParam mock;
525
526 EXPECT_CALL(mock, GetSize())
527 .WillOnce(Return(0))
528 .WillOnce(Return(1))
529 .WillOnce(Return(0));
530 EXPECT_CALL(mock, Push(_));
531 int n = 5;
532 EXPECT_CALL(mock, GetTop())
533 .WillOnce(ReturnRef(n));
534 EXPECT_CALL(mock, Pop())
535 .Times(AnyNumber());
536
537 EXPECT_EQ(0, mock.GetSize());
538 mock.Push(5);
539 EXPECT_EQ(1, mock.GetSize());
540 EXPECT_EQ(5, mock.GetTop());
541 mock.Pop();
542 EXPECT_EQ(0, mock.GetSize());
543 }
544
TYPED_TEST(TemplateMockTest,MethodWithCommaInReturnTypeWorks)545 TYPED_TEST(TemplateMockTest, MethodWithCommaInReturnTypeWorks) {
546 TypeParam mock;
547
548 const std::map<int, int> a_map;
549 EXPECT_CALL(mock, ReturnTypeWithComma())
550 .WillOnce(Return(a_map));
551 EXPECT_CALL(mock, ReturnTypeWithComma(1))
552 .WillOnce(Return(a_map));
553
554 EXPECT_EQ(a_map, mock.ReturnTypeWithComma());
555 EXPECT_EQ(a_map, mock.ReturnTypeWithComma(1));
556 }
557
558 #if GTEST_OS_WINDOWS
559 // Tests mocking template interfaces with calltype.
560
561 template <typename T>
562 class StackInterfaceWithCallType {
563 public:
~StackInterfaceWithCallType()564 virtual ~StackInterfaceWithCallType() {}
565
566 // Template parameter appears in function parameter.
567 STDMETHOD_(void, Push)(const T& value) = 0;
568 STDMETHOD_(void, Pop)() = 0;
569 STDMETHOD_(int, GetSize)() const = 0;
570 // Template parameter appears in function return type.
571 STDMETHOD_(const T&, GetTop)() const = 0;
572 };
573
574 template <typename T>
575 class MockStackWithCallType : public StackInterfaceWithCallType<T> {
576 public:
MockStackWithCallType()577 MockStackWithCallType() {}
578
579 MOCK_METHOD(void, Push, (const T& elem),
580 (Calltype(STDMETHODCALLTYPE), override));
581 MOCK_METHOD(void, Pop, (), (Calltype(STDMETHODCALLTYPE), override));
582 MOCK_METHOD(int, GetSize, (), (Calltype(STDMETHODCALLTYPE), override, const));
583 MOCK_METHOD(const T&, GetTop, (),
584 (Calltype(STDMETHODCALLTYPE), override, const));
585
586 private:
587 GTEST_DISALLOW_COPY_AND_ASSIGN_(MockStackWithCallType);
588 };
589
590 template <typename T>
591 class LegacyMockStackWithCallType : public StackInterfaceWithCallType<T> {
592 public:
LegacyMockStackWithCallType()593 LegacyMockStackWithCallType() {}
594
595 MOCK_METHOD1_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Push, void(const T& elem));
596 MOCK_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, Pop, void());
597 MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetSize, int());
598 MOCK_CONST_METHOD0_T_WITH_CALLTYPE(STDMETHODCALLTYPE, GetTop, const T&());
599
600 private:
601 GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockStackWithCallType);
602 };
603
604 template <typename T>
605 class TemplateMockTestWithCallType : public ::testing::Test {};
606 using TemplateMockTestWithCallTypeTypes =
607 ::testing::Types<MockStackWithCallType<int>,
608 LegacyMockStackWithCallType<int>>;
609 TYPED_TEST_SUITE(TemplateMockTestWithCallType,
610 TemplateMockTestWithCallTypeTypes);
611
612 // Tests that template mock with calltype works.
TYPED_TEST(TemplateMockTestWithCallType,Works)613 TYPED_TEST(TemplateMockTestWithCallType, Works) {
614 TypeParam mock;
615
616 EXPECT_CALL(mock, GetSize())
617 .WillOnce(Return(0))
618 .WillOnce(Return(1))
619 .WillOnce(Return(0));
620 EXPECT_CALL(mock, Push(_));
621 int n = 5;
622 EXPECT_CALL(mock, GetTop())
623 .WillOnce(ReturnRef(n));
624 EXPECT_CALL(mock, Pop())
625 .Times(AnyNumber());
626
627 EXPECT_EQ(0, mock.GetSize());
628 mock.Push(5);
629 EXPECT_EQ(1, mock.GetSize());
630 EXPECT_EQ(5, mock.GetTop());
631 mock.Pop();
632 EXPECT_EQ(0, mock.GetSize());
633 }
634 #endif // GTEST_OS_WINDOWS
635
636 #define MY_MOCK_METHODS1_ \
637 MOCK_METHOD(void, Overloaded, ()); \
638 MOCK_METHOD(int, Overloaded, (int), (const)); \
639 MOCK_METHOD(bool, Overloaded, (bool f, int n))
640
641 #define LEGACY_MY_MOCK_METHODS1_ \
642 MOCK_METHOD0(Overloaded, void()); \
643 MOCK_CONST_METHOD1(Overloaded, int(int n)); \
644 MOCK_METHOD2(Overloaded, bool(bool f, int n))
645
646 class MockOverloadedOnArgNumber {
647 public:
MockOverloadedOnArgNumber()648 MockOverloadedOnArgNumber() {}
649
650 MY_MOCK_METHODS1_;
651
652 private:
653 GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnArgNumber);
654 };
655
656 class LegacyMockOverloadedOnArgNumber {
657 public:
LegacyMockOverloadedOnArgNumber()658 LegacyMockOverloadedOnArgNumber() {}
659
660 LEGACY_MY_MOCK_METHODS1_;
661
662 private:
663 GTEST_DISALLOW_COPY_AND_ASSIGN_(LegacyMockOverloadedOnArgNumber);
664 };
665
666 template <typename T>
667 class OverloadedMockMethodTest : public ::testing::Test {};
668 using OverloadedMockMethodTestTypes =
669 ::testing::Types<MockOverloadedOnArgNumber,
670 LegacyMockOverloadedOnArgNumber>;
671 TYPED_TEST_SUITE(OverloadedMockMethodTest, OverloadedMockMethodTestTypes);
672
TYPED_TEST(OverloadedMockMethodTest,CanOverloadOnArgNumberInMacroBody)673 TYPED_TEST(OverloadedMockMethodTest, CanOverloadOnArgNumberInMacroBody) {
674 TypeParam mock;
675 EXPECT_CALL(mock, Overloaded());
676 EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
677 EXPECT_CALL(mock, Overloaded(true, 1)).WillOnce(Return(true));
678
679 mock.Overloaded();
680 EXPECT_EQ(2, mock.Overloaded(1));
681 EXPECT_TRUE(mock.Overloaded(true, 1));
682 }
683
684 #define MY_MOCK_METHODS2_ \
685 MOCK_CONST_METHOD1(Overloaded, int(int n)); \
686 MOCK_METHOD1(Overloaded, int(int n))
687
688 class MockOverloadedOnConstness {
689 public:
MockOverloadedOnConstness()690 MockOverloadedOnConstness() {}
691
692 MY_MOCK_METHODS2_;
693
694 private:
695 GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnConstness);
696 };
697
TEST(MockMethodOverloadedMockMethodTest,CanOverloadOnConstnessInMacroBody)698 TEST(MockMethodOverloadedMockMethodTest, CanOverloadOnConstnessInMacroBody) {
699 MockOverloadedOnConstness mock;
700 const MockOverloadedOnConstness* const_mock = &mock;
701 EXPECT_CALL(mock, Overloaded(1)).WillOnce(Return(2));
702 EXPECT_CALL(*const_mock, Overloaded(1)).WillOnce(Return(3));
703
704 EXPECT_EQ(2, mock.Overloaded(1));
705 EXPECT_EQ(3, const_mock->Overloaded(1));
706 }
707
TEST(MockMethodMockFunctionTest,WorksForVoidNullary)708 TEST(MockMethodMockFunctionTest, WorksForVoidNullary) {
709 MockFunction<void()> foo;
710 EXPECT_CALL(foo, Call());
711 foo.Call();
712 }
713
TEST(MockMethodMockFunctionTest,WorksForNonVoidNullary)714 TEST(MockMethodMockFunctionTest, WorksForNonVoidNullary) {
715 MockFunction<int()> foo;
716 EXPECT_CALL(foo, Call())
717 .WillOnce(Return(1))
718 .WillOnce(Return(2));
719 EXPECT_EQ(1, foo.Call());
720 EXPECT_EQ(2, foo.Call());
721 }
722
TEST(MockMethodMockFunctionTest,WorksForVoidUnary)723 TEST(MockMethodMockFunctionTest, WorksForVoidUnary) {
724 MockFunction<void(int)> foo;
725 EXPECT_CALL(foo, Call(1));
726 foo.Call(1);
727 }
728
TEST(MockMethodMockFunctionTest,WorksForNonVoidBinary)729 TEST(MockMethodMockFunctionTest, WorksForNonVoidBinary) {
730 MockFunction<int(bool, int)> foo;
731 EXPECT_CALL(foo, Call(false, 42))
732 .WillOnce(Return(1))
733 .WillOnce(Return(2));
734 EXPECT_CALL(foo, Call(true, Ge(100)))
735 .WillOnce(Return(3));
736 EXPECT_EQ(1, foo.Call(false, 42));
737 EXPECT_EQ(2, foo.Call(false, 42));
738 EXPECT_EQ(3, foo.Call(true, 120));
739 }
740
TEST(MockMethodMockFunctionTest,WorksFor10Arguments)741 TEST(MockMethodMockFunctionTest, WorksFor10Arguments) {
742 MockFunction<int(bool a0, char a1, int a2, int a3, int a4,
743 int a5, int a6, char a7, int a8, bool a9)> foo;
744 EXPECT_CALL(foo, Call(_, 'a', _, _, _, _, _, _, _, _))
745 .WillOnce(Return(1))
746 .WillOnce(Return(2));
747 EXPECT_EQ(1, foo.Call(false, 'a', 0, 0, 0, 0, 0, 'b', 0, true));
748 EXPECT_EQ(2, foo.Call(true, 'a', 0, 0, 0, 0, 0, 'b', 1, false));
749 }
750
TEST(MockMethodMockFunctionTest,AsStdFunction)751 TEST(MockMethodMockFunctionTest, AsStdFunction) {
752 MockFunction<int(int)> foo;
753 auto call = [](const std::function<int(int)> &f, int i) {
754 return f(i);
755 };
756 EXPECT_CALL(foo, Call(1)).WillOnce(Return(-1));
757 EXPECT_CALL(foo, Call(2)).WillOnce(Return(-2));
758 EXPECT_EQ(-1, call(foo.AsStdFunction(), 1));
759 EXPECT_EQ(-2, call(foo.AsStdFunction(), 2));
760 }
761
TEST(MockMethodMockFunctionTest,AsStdFunctionReturnsReference)762 TEST(MockMethodMockFunctionTest, AsStdFunctionReturnsReference) {
763 MockFunction<int&()> foo;
764 int value = 1;
765 EXPECT_CALL(foo, Call()).WillOnce(ReturnRef(value));
766 int& ref = foo.AsStdFunction()();
767 EXPECT_EQ(1, ref);
768 value = 2;
769 EXPECT_EQ(2, ref);
770 }
771
TEST(MockMethodMockFunctionTest,AsStdFunctionWithReferenceParameter)772 TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) {
773 MockFunction<int(int &)> foo;
774 auto call = [](const std::function<int(int& )> &f, int &i) {
775 return f(i);
776 };
777 int i = 42;
778 EXPECT_CALL(foo, Call(i)).WillOnce(Return(-1));
779 EXPECT_EQ(-1, call(foo.AsStdFunction(), i));
780 }
781
782 namespace {
783
784 template <typename Expected, typename F>
IsMockFunctionTemplateArgumentDeducedTo(const MockFunction<F> &)785 static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(
786 const MockFunction<F>&) {
787 return std::is_same<F, Expected>::value;
788 }
789
790 } // namespace
791
792 template <typename F>
793 class MockMethodMockFunctionSignatureTest : public Test {};
794
795 using MockMethodMockFunctionSignatureTypes =
796 Types<void(), int(), void(int), int(int), int(bool, int),
797 int(bool, char, int, int, int, int, int, char, int, bool)>;
798 TYPED_TEST_SUITE(MockMethodMockFunctionSignatureTest,
799 MockMethodMockFunctionSignatureTypes);
800
TYPED_TEST(MockMethodMockFunctionSignatureTest,IsMockFunctionTemplateArgumentDeducedForRawSignature)801 TYPED_TEST(MockMethodMockFunctionSignatureTest,
802 IsMockFunctionTemplateArgumentDeducedForRawSignature) {
803 using Argument = TypeParam;
804 MockFunction<Argument> foo;
805 EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<Argument>(foo));
806 }
807
TYPED_TEST(MockMethodMockFunctionSignatureTest,IsMockFunctionTemplateArgumentDeducedForStdFunction)808 TYPED_TEST(MockMethodMockFunctionSignatureTest,
809 IsMockFunctionTemplateArgumentDeducedForStdFunction) {
810 using Argument = std::function<TypeParam>;
811 MockFunction<Argument> foo;
812 EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<Argument>(foo));
813 }
814
TYPED_TEST(MockMethodMockFunctionSignatureTest,IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction)815 TYPED_TEST(
816 MockMethodMockFunctionSignatureTest,
817 IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) {
818 using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
819 using ForStdFunction =
820 decltype(&MockFunction<std::function<TypeParam>>::Call);
821 EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
822 }
823
TYPED_TEST(MockMethodMockFunctionSignatureTest,IsMockFunctionAsStdFunctionMethodSignatureTheSameForRawSignatureAndStdFunction)824 TYPED_TEST(
825 MockMethodMockFunctionSignatureTest,
826 IsMockFunctionAsStdFunctionMethodSignatureTheSameForRawSignatureAndStdFunction) {
827 using ForRawSignature = decltype(&MockFunction<TypeParam>::AsStdFunction);
828 using ForStdFunction =
829 decltype(&MockFunction<std::function<TypeParam>>::AsStdFunction);
830 EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
831 }
832
833 struct MockMethodSizes0 {
834 MOCK_METHOD(void, func, ());
835 };
836 struct MockMethodSizes1 {
837 MOCK_METHOD(void, func, (int));
838 };
839 struct MockMethodSizes2 {
840 MOCK_METHOD(void, func, (int, int));
841 };
842 struct MockMethodSizes3 {
843 MOCK_METHOD(void, func, (int, int, int));
844 };
845 struct MockMethodSizes4 {
846 MOCK_METHOD(void, func, (int, int, int, int));
847 };
848
849 struct LegacyMockMethodSizes0 {
850 MOCK_METHOD0(func, void());
851 };
852 struct LegacyMockMethodSizes1 {
853 MOCK_METHOD1(func, void(int));
854 };
855 struct LegacyMockMethodSizes2 {
856 MOCK_METHOD2(func, void(int, int));
857 };
858 struct LegacyMockMethodSizes3 {
859 MOCK_METHOD3(func, void(int, int, int));
860 };
861 struct LegacyMockMethodSizes4 {
862 MOCK_METHOD4(func, void(int, int, int, int));
863 };
864
865
TEST(MockMethodMockFunctionTest,MockMethodSizeOverhead)866 TEST(MockMethodMockFunctionTest, MockMethodSizeOverhead) {
867 EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes1));
868 EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes2));
869 EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes3));
870 EXPECT_EQ(sizeof(MockMethodSizes0), sizeof(MockMethodSizes4));
871
872 EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes1));
873 EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes2));
874 EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes3));
875 EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(LegacyMockMethodSizes4));
876
877 EXPECT_EQ(sizeof(LegacyMockMethodSizes0), sizeof(MockMethodSizes0));
878 }
879
880 void hasTwoParams(int, int);
881 void MaybeThrows();
882 void DoesntThrow() noexcept;
883 struct MockMethodNoexceptSpecifier {
884 MOCK_METHOD(void, func1, (), (noexcept));
885 MOCK_METHOD(void, func2, (), (noexcept(true)));
886 MOCK_METHOD(void, func3, (), (noexcept(false)));
887 MOCK_METHOD(void, func4, (), (noexcept(noexcept(MaybeThrows()))));
888 MOCK_METHOD(void, func5, (), (noexcept(noexcept(DoesntThrow()))));
889 MOCK_METHOD(void, func6, (), (noexcept(noexcept(DoesntThrow())), const));
890 MOCK_METHOD(void, func7, (), (const, noexcept(noexcept(DoesntThrow()))));
891 // Put commas in the noexcept expression
892 MOCK_METHOD(void, func8, (), (noexcept(noexcept(hasTwoParams(1, 2))), const));
893 };
894
TEST(MockMethodMockFunctionTest,NoexceptSpecifierPreserved)895 TEST(MockMethodMockFunctionTest, NoexceptSpecifierPreserved) {
896 EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func1()));
897 EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func2()));
898 EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func3()));
899 EXPECT_FALSE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func4()));
900 EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func5()));
901 EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func6()));
902 EXPECT_TRUE(noexcept(std::declval<MockMethodNoexceptSpecifier>().func7()));
903 EXPECT_EQ(noexcept(std::declval<MockMethodNoexceptSpecifier>().func8()),
904 noexcept(hasTwoParams(1, 2)));
905 }
906
907 } // namespace gmock_function_mocker_test
908 } // namespace testing
909