]>
Commit | Line | Data |
---|---|---|
1e59de90 TL |
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: | |
71 | TemplatedCopyable() {} | |
72 | ||
73 | template <typename U> | |
74 | TemplatedCopyable(const U& other) {} // NOLINT | |
75 | }; | |
76 | ||
77 | class FooInterface { | |
78 | public: | |
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: | |
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: | |
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: | |
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. | |
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. | |
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. | |
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. | |
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. | |
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. | |
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. | |
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. | |
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. | |
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. | |
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. | |
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 | ||
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 | ||
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. | |
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. | |
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. | |
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. | |
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 | ||
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: | |
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: | |
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. | |
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: | |
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: | |
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: | |
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. | |
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 | ||
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: | |
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: | |
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: | |
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. | |
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: | |
648 | MockOverloadedOnArgNumber() {} | |
649 | ||
650 | MY_MOCK_METHODS1_; | |
651 | ||
652 | private: | |
653 | GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnArgNumber); | |
654 | }; | |
655 | ||
656 | class LegacyMockOverloadedOnArgNumber { | |
657 | public: | |
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 | ||
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: | |
690 | MockOverloadedOnConstness() {} | |
691 | ||
692 | MY_MOCK_METHODS2_; | |
693 | ||
694 | private: | |
695 | GTEST_DISALLOW_COPY_AND_ASSIGN_(MockOverloadedOnConstness); | |
696 | }; | |
697 | ||
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 | ||
708 | TEST(MockMethodMockFunctionTest, WorksForVoidNullary) { | |
709 | MockFunction<void()> foo; | |
710 | EXPECT_CALL(foo, Call()); | |
711 | foo.Call(); | |
712 | } | |
713 | ||
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 | ||
723 | TEST(MockMethodMockFunctionTest, WorksForVoidUnary) { | |
724 | MockFunction<void(int)> foo; | |
725 | EXPECT_CALL(foo, Call(1)); | |
726 | foo.Call(1); | |
727 | } | |
728 | ||
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 | ||
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 | ||
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 | ||
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 | ||
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> | |
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 | ||
801 | TYPED_TEST(MockMethodMockFunctionSignatureTest, | |
802 | IsMockFunctionTemplateArgumentDeducedForRawSignature) { | |
803 | using Argument = TypeParam; | |
804 | MockFunction<Argument> foo; | |
805 | EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<Argument>(foo)); | |
806 | } | |
807 | ||
808 | TYPED_TEST(MockMethodMockFunctionSignatureTest, | |
809 | IsMockFunctionTemplateArgumentDeducedForStdFunction) { | |
810 | using Argument = std::function<TypeParam>; | |
811 | MockFunction<Argument> foo; | |
812 | EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<Argument>(foo)); | |
813 | } | |
814 | ||
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 | ||
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 | ||
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 | ||
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 |