1 | // Copyright 2008, Google Inc. |
2 | // All rights reserved. |
3 | // |
4 | // Redistribution and use in source and binary forms, with or without |
5 | // modification, are permitted provided that the following conditions are |
6 | // met: |
7 | // |
8 | // * Redistributions of source code must retain the above copyright |
9 | // notice, this list of conditions and the following disclaimer. |
10 | // * Redistributions in binary form must reproduce the above |
11 | // copyright notice, this list of conditions and the following disclaimer |
12 | // in the documentation and/or other materials provided with the |
13 | // distribution. |
14 | // * Neither the name of Google Inc. nor the names of its |
15 | // contributors may be used to endorse or promote products derived from |
16 | // this software without specific prior written permission. |
17 | // |
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 | |
30 | #include "gmock/gmock-nice-strict.h" |
31 | |
32 | #include <string> |
33 | #include <utility> |
34 | #include "gmock/gmock.h" |
35 | #include "gtest/gtest-spi.h" |
36 | #include "gtest/gtest.h" |
37 | |
38 | // This must not be defined inside the ::testing namespace, or it will |
39 | // clash with ::testing::Mock. |
40 | class Mock { |
41 | public: |
42 | Mock() {} |
43 | |
44 | MOCK_METHOD0(DoThis, void()); |
45 | |
46 | private: |
47 | GTEST_DISALLOW_COPY_AND_ASSIGN_(Mock); |
48 | }; |
49 | |
50 | namespace testing { |
51 | namespace gmock_nice_strict_test { |
52 | |
53 | using testing::GMOCK_FLAG(verbose); |
54 | using testing::HasSubstr; |
55 | using testing::NaggyMock; |
56 | using testing::NiceMock; |
57 | using testing::StrictMock; |
58 | |
59 | #if GTEST_HAS_STREAM_REDIRECTION |
60 | using testing::internal::CaptureStdout; |
61 | using testing::internal::GetCapturedStdout; |
62 | #endif |
63 | |
64 | // Class without default constructor. |
65 | class NotDefaultConstructible { |
66 | public: |
67 | explicit NotDefaultConstructible(int) {} |
68 | }; |
69 | |
70 | // Defines some mock classes needed by the tests. |
71 | |
72 | class Foo { |
73 | public: |
74 | virtual ~Foo() {} |
75 | |
76 | virtual void DoThis() = 0; |
77 | virtual int DoThat(bool flag) = 0; |
78 | }; |
79 | |
80 | class MockFoo : public Foo { |
81 | public: |
82 | MockFoo() {} |
83 | void Delete() { delete this; } |
84 | |
85 | MOCK_METHOD0(DoThis, void()); |
86 | MOCK_METHOD1(DoThat, int(bool flag)); |
87 | MOCK_METHOD0(ReturnNonDefaultConstructible, NotDefaultConstructible()); |
88 | |
89 | private: |
90 | GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo); |
91 | }; |
92 | |
93 | class MockBar { |
94 | public: |
95 | explicit MockBar(const std::string& s) : str_(s) {} |
96 | |
97 | MockBar(char a1, char a2, std::string a3, std::string a4, int a5, int a6, |
98 | const std::string& a7, const std::string& a8, bool a9, bool a10) { |
99 | str_ = std::string() + a1 + a2 + a3 + a4 + static_cast<char>(a5) + |
100 | static_cast<char>(a6) + a7 + a8 + (a9 ? 'T' : 'F') + (a10 ? 'T' : 'F'); |
101 | } |
102 | |
103 | virtual ~MockBar() {} |
104 | |
105 | const std::string& str() const { return str_; } |
106 | |
107 | MOCK_METHOD0(This, int()); |
108 | MOCK_METHOD2(That, std::string(int, bool)); |
109 | |
110 | private: |
111 | std::string str_; |
112 | |
113 | GTEST_DISALLOW_COPY_AND_ASSIGN_(MockBar); |
114 | }; |
115 | |
116 | |
117 | class MockBaz { |
118 | public: |
119 | class MoveOnly { |
120 | public: |
121 | MoveOnly() = default; |
122 | |
123 | MoveOnly(const MoveOnly&) = delete; |
124 | MoveOnly& operator=(const MoveOnly&) = delete; |
125 | |
126 | MoveOnly(MoveOnly&&) = default; |
127 | MoveOnly& operator=(MoveOnly&&) = default; |
128 | }; |
129 | |
130 | MockBaz(MoveOnly) {} |
131 | }; |
132 | |
133 | #if GTEST_HAS_STREAM_REDIRECTION |
134 | |
135 | // Tests that a raw mock generates warnings for uninteresting calls. |
136 | TEST(RawMockTest, WarningForUninterestingCall) { |
137 | const std::string saved_flag = GMOCK_FLAG(verbose); |
138 | GMOCK_FLAG(verbose) = "warning" ; |
139 | |
140 | MockFoo raw_foo; |
141 | |
142 | CaptureStdout(); |
143 | raw_foo.DoThis(); |
144 | raw_foo.DoThat(true); |
145 | EXPECT_THAT(GetCapturedStdout(), |
146 | HasSubstr("Uninteresting mock function call" )); |
147 | |
148 | GMOCK_FLAG(verbose) = saved_flag; |
149 | } |
150 | |
151 | // Tests that a raw mock generates warnings for uninteresting calls |
152 | // that delete the mock object. |
153 | TEST(RawMockTest, WarningForUninterestingCallAfterDeath) { |
154 | const std::string saved_flag = GMOCK_FLAG(verbose); |
155 | GMOCK_FLAG(verbose) = "warning" ; |
156 | |
157 | MockFoo* const raw_foo = new MockFoo; |
158 | |
159 | ON_CALL(*raw_foo, DoThis()) |
160 | .WillByDefault(Invoke(raw_foo, &MockFoo::Delete)); |
161 | |
162 | CaptureStdout(); |
163 | raw_foo->DoThis(); |
164 | EXPECT_THAT(GetCapturedStdout(), |
165 | HasSubstr("Uninteresting mock function call" )); |
166 | |
167 | GMOCK_FLAG(verbose) = saved_flag; |
168 | } |
169 | |
170 | // Tests that a raw mock generates informational logs for |
171 | // uninteresting calls. |
172 | TEST(RawMockTest, InfoForUninterestingCall) { |
173 | MockFoo raw_foo; |
174 | |
175 | const std::string saved_flag = GMOCK_FLAG(verbose); |
176 | GMOCK_FLAG(verbose) = "info" ; |
177 | CaptureStdout(); |
178 | raw_foo.DoThis(); |
179 | EXPECT_THAT(GetCapturedStdout(), |
180 | HasSubstr("Uninteresting mock function call" )); |
181 | |
182 | GMOCK_FLAG(verbose) = saved_flag; |
183 | } |
184 | |
185 | TEST(RawMockTest, IsNaggy_IsNice_IsStrict) { |
186 | MockFoo raw_foo; |
187 | EXPECT_TRUE(Mock::IsNaggy(&raw_foo)); |
188 | EXPECT_FALSE(Mock::IsNice(&raw_foo)); |
189 | EXPECT_FALSE(Mock::IsStrict(&raw_foo)); |
190 | } |
191 | |
192 | // Tests that a nice mock generates no warning for uninteresting calls. |
193 | TEST(NiceMockTest, NoWarningForUninterestingCall) { |
194 | NiceMock<MockFoo> nice_foo; |
195 | |
196 | CaptureStdout(); |
197 | nice_foo.DoThis(); |
198 | nice_foo.DoThat(true); |
199 | EXPECT_EQ("" , GetCapturedStdout()); |
200 | } |
201 | |
202 | // Tests that a nice mock generates no warning for uninteresting calls |
203 | // that delete the mock object. |
204 | TEST(NiceMockTest, NoWarningForUninterestingCallAfterDeath) { |
205 | NiceMock<MockFoo>* const nice_foo = new NiceMock<MockFoo>; |
206 | |
207 | ON_CALL(*nice_foo, DoThis()) |
208 | .WillByDefault(Invoke(nice_foo, &MockFoo::Delete)); |
209 | |
210 | CaptureStdout(); |
211 | nice_foo->DoThis(); |
212 | EXPECT_EQ("" , GetCapturedStdout()); |
213 | } |
214 | |
215 | // Tests that a nice mock generates informational logs for |
216 | // uninteresting calls. |
217 | TEST(NiceMockTest, InfoForUninterestingCall) { |
218 | NiceMock<MockFoo> nice_foo; |
219 | |
220 | const std::string saved_flag = GMOCK_FLAG(verbose); |
221 | GMOCK_FLAG(verbose) = "info" ; |
222 | CaptureStdout(); |
223 | nice_foo.DoThis(); |
224 | EXPECT_THAT(GetCapturedStdout(), |
225 | HasSubstr("Uninteresting mock function call" )); |
226 | |
227 | GMOCK_FLAG(verbose) = saved_flag; |
228 | } |
229 | |
230 | #endif // GTEST_HAS_STREAM_REDIRECTION |
231 | |
232 | // Tests that a nice mock allows expected calls. |
233 | TEST(NiceMockTest, AllowsExpectedCall) { |
234 | NiceMock<MockFoo> nice_foo; |
235 | |
236 | EXPECT_CALL(nice_foo, DoThis()); |
237 | nice_foo.DoThis(); |
238 | } |
239 | |
240 | // Tests that an unexpected call on a nice mock which returns a |
241 | // not-default-constructible type throws an exception and the exception contains |
242 | // the method's name. |
243 | TEST(NiceMockTest, ThrowsExceptionForUnknownReturnTypes) { |
244 | NiceMock<MockFoo> nice_foo; |
245 | #if GTEST_HAS_EXCEPTIONS |
246 | try { |
247 | nice_foo.ReturnNonDefaultConstructible(); |
248 | FAIL(); |
249 | } catch (const std::runtime_error& ex) { |
250 | EXPECT_THAT(ex.what(), HasSubstr("ReturnNonDefaultConstructible" )); |
251 | } |
252 | #else |
253 | EXPECT_DEATH_IF_SUPPORTED({ nice_foo.ReturnNonDefaultConstructible(); }, "" ); |
254 | #endif |
255 | } |
256 | |
257 | // Tests that an unexpected call on a nice mock fails. |
258 | TEST(NiceMockTest, UnexpectedCallFails) { |
259 | NiceMock<MockFoo> nice_foo; |
260 | |
261 | EXPECT_CALL(nice_foo, DoThis()).Times(0); |
262 | EXPECT_NONFATAL_FAILURE(nice_foo.DoThis(), "called more times than expected" ); |
263 | } |
264 | |
265 | // Tests that NiceMock works with a mock class that has a non-default |
266 | // constructor. |
267 | TEST(NiceMockTest, NonDefaultConstructor) { |
268 | NiceMock<MockBar> nice_bar("hi" ); |
269 | EXPECT_EQ("hi" , nice_bar.str()); |
270 | |
271 | nice_bar.This(); |
272 | nice_bar.That(5, true); |
273 | } |
274 | |
275 | // Tests that NiceMock works with a mock class that has a 10-ary |
276 | // non-default constructor. |
277 | TEST(NiceMockTest, NonDefaultConstructor10) { |
278 | NiceMock<MockBar> nice_bar('a', 'b', "c" , "d" , 'e', 'f', |
279 | "g" , "h" , true, false); |
280 | EXPECT_EQ("abcdefghTF" , nice_bar.str()); |
281 | |
282 | nice_bar.This(); |
283 | nice_bar.That(5, true); |
284 | } |
285 | |
286 | TEST(NiceMockTest, AllowLeak) { |
287 | NiceMock<MockFoo>* leaked = new NiceMock<MockFoo>; |
288 | Mock::AllowLeak(leaked); |
289 | EXPECT_CALL(*leaked, DoThis()); |
290 | leaked->DoThis(); |
291 | } |
292 | |
293 | TEST(NiceMockTest, MoveOnlyConstructor) { |
294 | NiceMock<MockBaz> nice_baz(MockBaz::MoveOnly{}); |
295 | } |
296 | |
297 | // Tests that NiceMock<Mock> compiles where Mock is a user-defined |
298 | // class (as opposed to ::testing::Mock). |
299 | TEST(NiceMockTest, AcceptsClassNamedMock) { |
300 | NiceMock< ::Mock> nice; |
301 | EXPECT_CALL(nice, DoThis()); |
302 | nice.DoThis(); |
303 | } |
304 | |
305 | TEST(NiceMockTest, IsNaggy_IsNice_IsStrict) { |
306 | NiceMock<MockFoo> nice_foo; |
307 | EXPECT_FALSE(Mock::IsNaggy(&nice_foo)); |
308 | EXPECT_TRUE(Mock::IsNice(&nice_foo)); |
309 | EXPECT_FALSE(Mock::IsStrict(&nice_foo)); |
310 | } |
311 | |
312 | #if GTEST_HAS_STREAM_REDIRECTION |
313 | |
314 | // Tests that a naggy mock generates warnings for uninteresting calls. |
315 | TEST(NaggyMockTest, WarningForUninterestingCall) { |
316 | const std::string saved_flag = GMOCK_FLAG(verbose); |
317 | GMOCK_FLAG(verbose) = "warning" ; |
318 | |
319 | NaggyMock<MockFoo> naggy_foo; |
320 | |
321 | CaptureStdout(); |
322 | naggy_foo.DoThis(); |
323 | naggy_foo.DoThat(true); |
324 | EXPECT_THAT(GetCapturedStdout(), |
325 | HasSubstr("Uninteresting mock function call" )); |
326 | |
327 | GMOCK_FLAG(verbose) = saved_flag; |
328 | } |
329 | |
330 | // Tests that a naggy mock generates a warning for an uninteresting call |
331 | // that deletes the mock object. |
332 | TEST(NaggyMockTest, WarningForUninterestingCallAfterDeath) { |
333 | const std::string saved_flag = GMOCK_FLAG(verbose); |
334 | GMOCK_FLAG(verbose) = "warning" ; |
335 | |
336 | NaggyMock<MockFoo>* const naggy_foo = new NaggyMock<MockFoo>; |
337 | |
338 | ON_CALL(*naggy_foo, DoThis()) |
339 | .WillByDefault(Invoke(naggy_foo, &MockFoo::Delete)); |
340 | |
341 | CaptureStdout(); |
342 | naggy_foo->DoThis(); |
343 | EXPECT_THAT(GetCapturedStdout(), |
344 | HasSubstr("Uninteresting mock function call" )); |
345 | |
346 | GMOCK_FLAG(verbose) = saved_flag; |
347 | } |
348 | |
349 | #endif // GTEST_HAS_STREAM_REDIRECTION |
350 | |
351 | // Tests that a naggy mock allows expected calls. |
352 | TEST(NaggyMockTest, AllowsExpectedCall) { |
353 | NaggyMock<MockFoo> naggy_foo; |
354 | |
355 | EXPECT_CALL(naggy_foo, DoThis()); |
356 | naggy_foo.DoThis(); |
357 | } |
358 | |
359 | // Tests that an unexpected call on a naggy mock fails. |
360 | TEST(NaggyMockTest, UnexpectedCallFails) { |
361 | NaggyMock<MockFoo> naggy_foo; |
362 | |
363 | EXPECT_CALL(naggy_foo, DoThis()).Times(0); |
364 | EXPECT_NONFATAL_FAILURE(naggy_foo.DoThis(), |
365 | "called more times than expected" ); |
366 | } |
367 | |
368 | // Tests that NaggyMock works with a mock class that has a non-default |
369 | // constructor. |
370 | TEST(NaggyMockTest, NonDefaultConstructor) { |
371 | NaggyMock<MockBar> naggy_bar("hi" ); |
372 | EXPECT_EQ("hi" , naggy_bar.str()); |
373 | |
374 | naggy_bar.This(); |
375 | naggy_bar.That(5, true); |
376 | } |
377 | |
378 | // Tests that NaggyMock works with a mock class that has a 10-ary |
379 | // non-default constructor. |
380 | TEST(NaggyMockTest, NonDefaultConstructor10) { |
381 | NaggyMock<MockBar> naggy_bar('0', '1', "2" , "3" , '4', '5', |
382 | "6" , "7" , true, false); |
383 | EXPECT_EQ("01234567TF" , naggy_bar.str()); |
384 | |
385 | naggy_bar.This(); |
386 | naggy_bar.That(5, true); |
387 | } |
388 | |
389 | TEST(NaggyMockTest, AllowLeak) { |
390 | NaggyMock<MockFoo>* leaked = new NaggyMock<MockFoo>; |
391 | Mock::AllowLeak(leaked); |
392 | EXPECT_CALL(*leaked, DoThis()); |
393 | leaked->DoThis(); |
394 | } |
395 | |
396 | TEST(NaggyMockTest, MoveOnlyConstructor) { |
397 | NaggyMock<MockBaz> naggy_baz(MockBaz::MoveOnly{}); |
398 | } |
399 | |
400 | // Tests that NaggyMock<Mock> compiles where Mock is a user-defined |
401 | // class (as opposed to ::testing::Mock). |
402 | TEST(NaggyMockTest, AcceptsClassNamedMock) { |
403 | NaggyMock< ::Mock> naggy; |
404 | EXPECT_CALL(naggy, DoThis()); |
405 | naggy.DoThis(); |
406 | } |
407 | |
408 | TEST(NaggyMockTest, IsNaggy_IsNice_IsStrict) { |
409 | NaggyMock<MockFoo> naggy_foo; |
410 | EXPECT_TRUE(Mock::IsNaggy(&naggy_foo)); |
411 | EXPECT_FALSE(Mock::IsNice(&naggy_foo)); |
412 | EXPECT_FALSE(Mock::IsStrict(&naggy_foo)); |
413 | } |
414 | |
415 | // Tests that a strict mock allows expected calls. |
416 | TEST(StrictMockTest, AllowsExpectedCall) { |
417 | StrictMock<MockFoo> strict_foo; |
418 | |
419 | EXPECT_CALL(strict_foo, DoThis()); |
420 | strict_foo.DoThis(); |
421 | } |
422 | |
423 | // Tests that an unexpected call on a strict mock fails. |
424 | TEST(StrictMockTest, UnexpectedCallFails) { |
425 | StrictMock<MockFoo> strict_foo; |
426 | |
427 | EXPECT_CALL(strict_foo, DoThis()).Times(0); |
428 | EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(), |
429 | "called more times than expected" ); |
430 | } |
431 | |
432 | // Tests that an uninteresting call on a strict mock fails. |
433 | TEST(StrictMockTest, UninterestingCallFails) { |
434 | StrictMock<MockFoo> strict_foo; |
435 | |
436 | EXPECT_NONFATAL_FAILURE(strict_foo.DoThis(), |
437 | "Uninteresting mock function call" ); |
438 | } |
439 | |
440 | // Tests that an uninteresting call on a strict mock fails, even if |
441 | // the call deletes the mock object. |
442 | TEST(StrictMockTest, UninterestingCallFailsAfterDeath) { |
443 | StrictMock<MockFoo>* const strict_foo = new StrictMock<MockFoo>; |
444 | |
445 | ON_CALL(*strict_foo, DoThis()) |
446 | .WillByDefault(Invoke(strict_foo, &MockFoo::Delete)); |
447 | |
448 | EXPECT_NONFATAL_FAILURE(strict_foo->DoThis(), |
449 | "Uninteresting mock function call" ); |
450 | } |
451 | |
452 | // Tests that StrictMock works with a mock class that has a |
453 | // non-default constructor. |
454 | TEST(StrictMockTest, NonDefaultConstructor) { |
455 | StrictMock<MockBar> strict_bar("hi" ); |
456 | EXPECT_EQ("hi" , strict_bar.str()); |
457 | |
458 | EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true), |
459 | "Uninteresting mock function call" ); |
460 | } |
461 | |
462 | // Tests that StrictMock works with a mock class that has a 10-ary |
463 | // non-default constructor. |
464 | TEST(StrictMockTest, NonDefaultConstructor10) { |
465 | StrictMock<MockBar> strict_bar('a', 'b', "c" , "d" , 'e', 'f', |
466 | "g" , "h" , true, false); |
467 | EXPECT_EQ("abcdefghTF" , strict_bar.str()); |
468 | |
469 | EXPECT_NONFATAL_FAILURE(strict_bar.That(5, true), |
470 | "Uninteresting mock function call" ); |
471 | } |
472 | |
473 | TEST(StrictMockTest, AllowLeak) { |
474 | StrictMock<MockFoo>* leaked = new StrictMock<MockFoo>; |
475 | Mock::AllowLeak(leaked); |
476 | EXPECT_CALL(*leaked, DoThis()); |
477 | leaked->DoThis(); |
478 | } |
479 | |
480 | TEST(StrictMockTest, MoveOnlyConstructor) { |
481 | StrictMock<MockBaz> strict_baz(MockBaz::MoveOnly{}); |
482 | } |
483 | |
484 | // Tests that StrictMock<Mock> compiles where Mock is a user-defined |
485 | // class (as opposed to ::testing::Mock). |
486 | TEST(StrictMockTest, AcceptsClassNamedMock) { |
487 | StrictMock< ::Mock> strict; |
488 | EXPECT_CALL(strict, DoThis()); |
489 | strict.DoThis(); |
490 | } |
491 | |
492 | TEST(StrictMockTest, IsNaggy_IsNice_IsStrict) { |
493 | StrictMock<MockFoo> strict_foo; |
494 | EXPECT_FALSE(Mock::IsNaggy(&strict_foo)); |
495 | EXPECT_FALSE(Mock::IsNice(&strict_foo)); |
496 | EXPECT_TRUE(Mock::IsStrict(&strict_foo)); |
497 | } |
498 | |
499 | } // namespace gmock_nice_strict_test |
500 | } // namespace testing |
501 | |