Completed
Branch development (b1b115)
by Johannes
10:28
created

ContainerTest   F

Complexity

Total Complexity 133

Size/Duplication

Total Lines 1250
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 133
c 0
b 0
f 0
dl 0
loc 1250
rs 0.8

How to fix   Complexity   

Complex Class

Complex classes like ContainerTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ContainerTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Mockery
4
 *
5
 * LICENSE
6
 *
7
 * This source file is subject to the new BSD license that is bundled
8
 * with this package in the file LICENSE.txt.
9
 * It is also available through the world-wide-web at this URL:
10
 * http://github.com/padraic/mockery/master/LICENSE
11
 * If you did not receive a copy of the license and are unable to
12
 * obtain it through the world-wide-web, please send an email
13
 * to [email protected] so we can send you a copy immediately.
14
 *
15
 * @category   Mockery
16
 * @package    Mockery
17
 * @subpackage UnitTests
18
 * @copyright  Copyright (c) 2010-2014 Pádraic Brady (http://blog.astrumfutura.com)
19
 * @license    http://github.com/padraic/mockery/blob/master/LICENSE New BSD License
20
 */
21
22
use Mockery\Generator\MockConfigurationBuilder;
23
use Mockery\Adapter\Phpunit\MockeryTestCase;
24
25
class ContainerTest extends MockeryTestCase
26
{
27
28
    /** @var Mockery\Container */
29
    private $container;
30
31
    public function setup()
32
    {
33
        $this->container = new Mockery\Container(Mockery::getDefaultGenerator(), new Mockery\Loader\EvalLoader());
34
    }
35
36
    public function teardown()
37
    {
38
        $this->container->mockery_close();
39
    }
40
41
    public function testSimplestMockCreation()
42
    {
43
        $m = $this->container->mock();
44
        $m->shouldReceive('foo')->andReturn('bar');
45
        $this->assertEquals('bar', $m->foo());
46
    }
47
48
    public function testGetKeyOfDemeterMockShouldReturnKeyWhenMatchingMock()
49
    {
50
        $m = $this->container->mock();
51
        $m->shouldReceive('foo->bar');
52
        $this->assertRegExp(
53
            '/Mockery_(\d+)__demeter_foo/',
54
            $this->container->getKeyOfDemeterMockFor('foo')
55
        );
56
    }
57
    public function testGetKeyOfDemeterMockShouldReturnNullWhenNoMatchingMock()
58
    {
59
        $method = 'unknownMethod';
60
        $this->assertNull($this->container->getKeyOfDemeterMockFor($method));
61
62
        $m = $this->container->mock();
63
        $m->shouldReceive('method');
64
        $this->assertNull($this->container->getKeyOfDemeterMockFor($method));
65
66
        $m->shouldReceive('foo->bar');
67
        $this->assertNull($this->container->getKeyOfDemeterMockFor($method));
68
    }
69
70
71
    public function testNamedMocksAddNameToExceptions()
72
    {
73
        $m = $this->container->mock('Foo');
74
        $m->shouldReceive('foo')->with(1)->andReturn('bar');
75
        try {
76
            $m->foo();
77
        } catch (\Mockery\Exception $e) {
78
            $this->assertTrue((bool) preg_match("/Foo/", $e->getMessage()));
79
        }
80
    }
81
82
    public function testSimpleMockWithArrayDefs()
83
    {
84
        $m = $this->container->mock(array('foo'=>1, 'bar'=>2));
85
        $this->assertEquals(1, $m->foo());
86
        $this->assertEquals(2, $m->bar());
87
    }
88
89
    public function testSimpleMockWithArrayDefsCanBeOverridden()
90
    {
91
        // eg. In shared test setup
92
        $m = $this->container->mock(array('foo' => 1, 'bar' => 2));
93
94
        // and then overridden in one test
95
        $m->shouldReceive('foo')->with('baz')->once()->andReturn(2);
96
        $m->shouldReceive('bar')->with('baz')->once()->andReturn(42);
97
98
        $this->assertEquals(2, $m->foo('baz'));
99
        $this->assertEquals(42, $m->bar('baz'));
100
    }
101
102
    public function testNamedMockWithArrayDefs()
103
    {
104
        $m = $this->container->mock('Foo', array('foo'=>1, 'bar'=>2));
105
        $this->assertEquals(1, $m->foo());
106
        $this->assertEquals(2, $m->bar());
107
        try {
108
            $m->f();
109
        } catch (BadMethodCallException $e) {
110
            $this->assertTrue((bool) preg_match("/Foo/", $e->getMessage()));
111
        }
112
    }
113
114
    public function testNamedMockWithArrayDefsCanBeOverridden()
115
    {
116
        // eg. In shared test setup
117
        $m = $this->container->mock('Foo', array('foo' => 1));
118
119
        // and then overridden in one test
120
        $m->shouldReceive('foo')->with('bar')->once()->andReturn(2);
121
122
        $this->assertEquals(2, $m->foo('bar'));
123
124
        try {
125
            $m->f();
126
        } catch (BadMethodCallException $e) {
127
            $this->assertTrue((bool) preg_match("/Foo/", $e->getMessage()));
128
        }
129
    }
130
131
    public function testNamedMockMultipleInterfaces()
132
    {
133
        $m = $this->container->mock('stdClass, ArrayAccess, Countable', array('foo'=>1, 'bar'=>2));
134
        $this->assertEquals(1, $m->foo());
135
        $this->assertEquals(2, $m->bar());
136
        try {
137
            $m->f();
138
        } catch (BadMethodCallException $e) {
139
            $this->assertTrue((bool) preg_match("/stdClass/", $e->getMessage()));
140
            $this->assertTrue((bool) preg_match("/ArrayAccess/", $e->getMessage()));
141
            $this->assertTrue((bool) preg_match("/Countable/", $e->getMessage()));
142
        }
143
    }
144
145
    public function testNamedMockWithConstructorArgs()
146
    {
147
        $m = $this->container->mock("MockeryTest_ClassConstructor2[foo]", array($param1 = new stdClass()));
148
        $m->shouldReceive("foo")->andReturn(123);
149
        $this->assertEquals(123, $m->foo());
150
        $this->assertEquals($param1, $m->getParam1());
151
    }
152
153
    public function testNamedMockWithConstructorArgsAndArrayDefs()
154
    {
155
        $m = $this->container->mock(
156
            "MockeryTest_ClassConstructor2[foo]",
157
            array($param1 = new stdClass()),
158
            array("foo" => 123)
159
        );
160
        $this->assertEquals(123, $m->foo());
161
        $this->assertEquals($param1, $m->getParam1());
162
    }
163
164
    public function testNamedMockWithConstructorArgsWithInternalCallToMockedMethod()
165
    {
166
        $m = $this->container->mock("MockeryTest_ClassConstructor2[foo]", array($param1 = new stdClass()));
167
        $m->shouldReceive("foo")->andReturn(123);
168
        $this->assertEquals(123, $m->bar());
169
    }
170
171
    public function testNamedMockWithConstructorArgsButNoQuickDefsShouldLeaveConstructorIntact()
172
    {
173
        $m = $this->container->mock("MockeryTest_ClassConstructor2", array($param1 = new stdClass()));
174
        $m->shouldDeferMissing();
175
        $this->assertEquals($param1, $m->getParam1());
176
    }
177
178
    public function testNamedMockWithShouldDeferMissing()
179
    {
180
        $m = $this->container->mock("MockeryTest_ClassConstructor2", array($param1 = new stdClass()));
181
        $m->shouldDeferMissing();
182
        $this->assertEquals('foo', $m->bar());
183
        $m->shouldReceive("bar")->andReturn(123);
184
        $this->assertEquals(123, $m->bar());
185
    }
186
187
    /**
188
     * @expectedException BadMethodCallException
189
     */
190
    public function testNamedMockWithShouldDeferMissingThrowsIfNotAvailable()
191
    {
192
        $m = $this->container->mock("MockeryTest_ClassConstructor2", array($param1 = new stdClass()));
193
        $m->shouldDeferMissing();
194
        $m->foorbar123();
195
    }
196
197
    public function testMockingAKnownConcreteClassSoMockInheritsClassType()
198
    {
199
        $m = $this->container->mock('stdClass');
200
        $m->shouldReceive('foo')->andReturn('bar');
201
        $this->assertEquals('bar', $m->foo());
202
        $this->assertTrue($m instanceof stdClass);
203
    }
204
205
    public function testMockingAKnownUserClassSoMockInheritsClassType()
206
    {
207
        $m = $this->container->mock('MockeryTest_TestInheritedType');
208
        $this->assertTrue($m instanceof MockeryTest_TestInheritedType);
209
    }
210
211
    public function testMockingAConcreteObjectCreatesAPartialWithoutError()
212
    {
213
        $m = $this->container->mock(new stdClass);
214
        $m->shouldReceive('foo')->andReturn('bar');
215
        $this->assertEquals('bar', $m->foo());
216
        $this->assertTrue($m instanceof stdClass);
217
    }
218
219
    public function testCreatingAPartialAllowsDynamicExpectationsAndPassesThroughUnexpectedMethods()
220
    {
221
        $m = $this->container->mock(new MockeryTestFoo);
222
        $m->shouldReceive('bar')->andReturn('bar');
223
        $this->assertEquals('bar', $m->bar());
224
        $this->assertEquals('foo', $m->foo());
225
        $this->assertTrue($m instanceof MockeryTestFoo);
226
    }
227
228
    public function testCreatingAPartialAllowsExpectationsToInterceptCallsToImplementedMethods()
229
    {
230
        $m = $this->container->mock(new MockeryTestFoo2);
231
        $m->shouldReceive('bar')->andReturn('baz');
232
        $this->assertEquals('baz', $m->bar());
233
        $this->assertEquals('foo', $m->foo());
234
        $this->assertTrue($m instanceof MockeryTestFoo2);
235
    }
236
237
    public function testBlockForwardingToPartialObject()
238
    {
239
        $m = $this->container->mock(new MockeryTestBar1, array('foo'=>1, Mockery\Container::BLOCKS => array('method1')));
240
        $this->assertSame($m, $m->method1());
241
    }
242
243
    public function testPartialWithArrayDefs()
244
    {
245
        $m = $this->container->mock(new MockeryTestBar1, array('foo'=>1, Mockery\Container::BLOCKS => array('method1')));
246
        $this->assertEquals(1, $m->foo());
247
    }
248
249
    public function testPassingClosureAsFinalParameterUsedToDefineExpectations()
250
    {
251
        $m = $this->container->mock('foo', function ($m) {
252
            $m->shouldReceive('foo')->once()->andReturn('bar');
253
        });
254
        $this->assertEquals('bar', $m->foo());
255
    }
256
257
    /**
258
     * @expectedException \Mockery\Exception
259
     */
260
    public function testMockingAKnownConcreteFinalClassThrowsErrors_OnlyPartialMocksCanMockFinalElements()
261
    {
262
        $m = $this->container->mock('MockeryFoo3');
263
    }
264
265
    public function testMockingAKnownConcreteClassWithFinalMethodsThrowsNoException()
266
    {
267
        $m = $this->container->mock('MockeryFoo4');
268
    }
269
270
    /**
271
     * @group finalclass
272
     */
273
    public function testFinalClassesCanBePartialMocks()
274
    {
275
        $m = $this->container->mock(new MockeryFoo3);
276
        $m->shouldReceive('foo')->andReturn('baz');
277
        $this->assertEquals('baz', $m->foo());
278
        $this->assertFalse($m instanceof MockeryFoo3);
279
    }
280
281
    public function testSplClassWithFinalMethodsCanBeMocked()
282
    {
283
        $m = $this->container->mock('SplFileInfo');
284
        $m->shouldReceive('foo')->andReturn('baz');
285
        $this->assertEquals('baz', $m->foo());
286
        $this->assertTrue($m instanceof SplFileInfo);
287
    }
288
289
    public function testSplClassWithFinalMethodsCanBeMockedMultipleTimes()
290
    {
291
        $this->container->mock('SplFileInfo');
292
        $m = $this->container->mock('SplFileInfo');
293
        $m->shouldReceive('foo')->andReturn('baz');
294
        $this->assertEquals('baz', $m->foo());
295
        $this->assertTrue($m instanceof SplFileInfo);
296
    }
297
298
    public function testClassesWithFinalMethodsCanBeProxyPartialMocks()
299
    {
300
        $m = $this->container->mock(new MockeryFoo4);
301
        $m->shouldReceive('foo')->andReturn('baz');
302
        $this->assertEquals('baz', $m->foo());
303
        $this->assertEquals('bar', $m->bar());
304
        $this->assertTrue($m instanceof MockeryFoo4);
305
    }
306
307
    public function testClassesWithFinalMethodsCanBeProperPartialMocks()
308
    {
309
        $m = $this->container->mock('MockeryFoo4[bar]');
310
        $m->shouldReceive('bar')->andReturn('baz');
311
        $this->assertEquals('baz', $m->foo());
312
        $this->assertEquals('baz', $m->bar());
313
        $this->assertTrue($m instanceof MockeryFoo4);
314
    }
315
316
    public function testClassesWithFinalMethodsCanBeProperPartialMocksButFinalMethodsNotPartialed()
317
    {
318
        $m = $this->container->mock('MockeryFoo4[foo]');
319
        $m->shouldReceive('foo')->andReturn('foo');
320
        $this->assertEquals('baz', $m->foo()); // partial expectation ignored - will fail callcount assertion
321
        $this->assertTrue($m instanceof MockeryFoo4);
322
    }
323
324
    public function testSplfileinfoClassMockPassesUserExpectations()
325
    {
326
        $file = $this->container->mock('SplFileInfo[getFilename,getPathname,getExtension,getMTime]', array(__FILE__));
327
        $file->shouldReceive('getFilename')->once()->andReturn('foo');
328
        $file->shouldReceive('getPathname')->once()->andReturn('path/to/foo');
329
        $file->shouldReceive('getExtension')->once()->andReturn('css');
330
        $file->shouldReceive('getMTime')->once()->andReturn(time());
331
    }
332
333
    public function testCanMockInterface()
334
    {
335
        $m = $this->container->mock('MockeryTest_Interface');
336
        $this->assertTrue($m instanceof MockeryTest_Interface);
337
    }
338
339
    public function testCanMockSpl()
340
    {
341
        $m = $this->container->mock('\\SplFixedArray');
342
        $this->assertTrue($m instanceof SplFixedArray);
343
    }
344
345
    public function testCanMockInterfaceWithAbstractMethod()
346
    {
347
        $m = $this->container->mock('MockeryTest_InterfaceWithAbstractMethod');
348
        $this->assertTrue($m instanceof MockeryTest_InterfaceWithAbstractMethod);
349
        $m->shouldReceive('foo')->andReturn(1);
350
        $this->assertEquals(1, $m->foo());
351
    }
352
353
    public function testCanMockAbstractWithAbstractProtectedMethod()
354
    {
355
        $m = $this->container->mock('MockeryTest_AbstractWithAbstractMethod');
356
        $this->assertTrue($m instanceof MockeryTest_AbstractWithAbstractMethod);
357
    }
358
359
    public function testCanMockInterfaceWithPublicStaticMethod()
360
    {
361
        $m = $this->container->mock('MockeryTest_InterfaceWithPublicStaticMethod');
362
        $this->assertTrue($m instanceof MockeryTest_InterfaceWithPublicStaticMethod);
363
    }
364
365
    public function testCanMockClassWithConstructor()
366
    {
367
        $m = $this->container->mock('MockeryTest_ClassConstructor');
368
        $this->assertTrue($m instanceof MockeryTest_ClassConstructor);
369
    }
370
371
    public function testCanMockClassWithConstructorNeedingClassArgs()
372
    {
373
        $m = $this->container->mock('MockeryTest_ClassConstructor2');
374
        $this->assertTrue($m instanceof MockeryTest_ClassConstructor2);
375
    }
376
377
    /**
378
     * @group partial
379
     */
380
    public function testCanPartiallyMockANormalClass()
381
    {
382
        $m = $this->container->mock('MockeryTest_PartialNormalClass[foo]');
383
        $this->assertTrue($m instanceof MockeryTest_PartialNormalClass);
384
        $m->shouldReceive('foo')->andReturn('cba');
385
        $this->assertEquals('abc', $m->bar());
386
        $this->assertEquals('cba', $m->foo());
387
    }
388
389
    /**
390
     * @group partial
391
     */
392
    public function testCanPartiallyMockAnAbstractClass()
393
    {
394
        $m = $this->container->mock('MockeryTest_PartialAbstractClass[foo]');
395
        $this->assertTrue($m instanceof MockeryTest_PartialAbstractClass);
396
        $m->shouldReceive('foo')->andReturn('cba');
397
        $this->assertEquals('abc', $m->bar());
398
        $this->assertEquals('cba', $m->foo());
399
    }
400
401
    /**
402
     * @group partial
403
     */
404
    public function testCanPartiallyMockANormalClassWith2Methods()
405
    {
406
        $m = $this->container->mock('MockeryTest_PartialNormalClass2[foo, baz]');
407
        $this->assertTrue($m instanceof MockeryTest_PartialNormalClass2);
408
        $m->shouldReceive('foo')->andReturn('cba');
409
        $m->shouldReceive('baz')->andReturn('cba');
410
        $this->assertEquals('abc', $m->bar());
411
        $this->assertEquals('cba', $m->foo());
412
        $this->assertEquals('cba', $m->baz());
413
    }
414
415
    /**
416
     * @group partial
417
     */
418
    public function testCanPartiallyMockAnAbstractClassWith2Methods()
419
    {
420
        $m = $this->container->mock('MockeryTest_PartialAbstractClass2[foo,baz]');
421
        $this->assertTrue($m instanceof MockeryTest_PartialAbstractClass2);
422
        $m->shouldReceive('foo')->andReturn('cba');
423
        $m->shouldReceive('baz')->andReturn('cba');
424
        $this->assertEquals('abc', $m->bar());
425
        $this->assertEquals('cba', $m->foo());
426
        $this->assertEquals('cba', $m->baz());
427
    }
428
429
    /**
430
     * @expectedException \Mockery\Exception
431
     * @group partial
432
     */
433
    public function testThrowsExceptionIfSettingExpectationForNonMockedMethodOfPartialMock()
434
    {
435
        $this->markTestSkipped('For now...');
436
        $m = $this->container->mock('MockeryTest_PartialNormalClass[foo]');
437
        $this->assertTrue($m instanceof MockeryTest_PartialNormalClass);
438
        $m->shouldReceive('bar')->andReturn('cba');
439
    }
440
441
    /**
442
     * @expectedException \Mockery\Exception
443
     * @group partial
444
     */
445
    public function testThrowsExceptionIfClassOrInterfaceForPartialMockDoesNotExist()
446
    {
447
        $m = $this->container->mock('MockeryTest_PartialNormalClassXYZ[foo]');
448
    }
449
450
    /**
451
     * @group issue/4
452
     */
453
    public function testCanMockClassContainingMagicCallMethod()
454
    {
455
        $m = $this->container->mock('MockeryTest_Call1');
456
        $this->assertTrue($m instanceof MockeryTest_Call1);
457
    }
458
459
    /**
460
     * @group issue/4
461
     */
462
    public function testCanMockClassContainingMagicCallMethodWithoutTypeHinting()
463
    {
464
        $m = $this->container->mock('MockeryTest_Call2');
465
        $this->assertTrue($m instanceof MockeryTest_Call2);
466
    }
467
468
    /**
469
     * @group issue/14
470
     */
471
    public function testCanMockClassContainingAPublicWakeupMethod()
472
    {
473
        $m = $this->container->mock('MockeryTest_Wakeup1');
474
        $this->assertTrue($m instanceof MockeryTest_Wakeup1);
475
    }
476
477
    /**
478
     * @group issue/18
479
     */
480
    public function testCanMockClassUsingMagicCallMethodsInPlaceOfNormalMethods()
481
    {
482
        $m = Mockery::mock('Gateway');
483
        $m->shouldReceive('iDoSomethingReallyCoolHere');
484
        $m->iDoSomethingReallyCoolHere();
485
    }
486
487
    /**
488
     * @group issue/18
489
     */
490
    public function testCanPartialMockObjectUsingMagicCallMethodsInPlaceOfNormalMethods()
491
    {
492
        $m = Mockery::mock(new Gateway);
493
        $m->shouldReceive('iDoSomethingReallyCoolHere');
494
        $m->iDoSomethingReallyCoolHere();
495
    }
496
497
    /**
498
     * @group issue/13
499
     */
500
    public function testCanMockClassWhereMethodHasReferencedParameter()
501
    {
502
        $m = Mockery::mock(new MockeryTest_MethodParamRef);
503
    }
504
505
    /**
506
     * @group issue/13
507
     */
508
    public function testCanPartiallyMockObjectWhereMethodHasReferencedParameter()
509
    {
510
        $m = Mockery::mock(new MockeryTest_MethodParamRef2);
511
    }
512
513
    /**
514
     * @group issue/11
515
     */
516
    public function testMockingAKnownConcreteClassCanBeGrantedAnArbitraryClassType()
517
    {
518
        $m = $this->container->mock('alias:MyNamespace\MyClass');
519
        $m->shouldReceive('foo')->andReturn('bar');
520
        $this->assertEquals('bar', $m->foo());
521
        $this->assertTrue($m instanceof MyNamespace\MyClass);
522
    }
523
524
    /**
525
     * @group issue/15
526
     */
527
    public function testCanMockMultipleInterfaces()
528
    {
529
        $m = $this->container->mock('MockeryTest_Interface1, MockeryTest_Interface2');
530
        $this->assertTrue($m instanceof MockeryTest_Interface1);
531
        $this->assertTrue($m instanceof MockeryTest_Interface2);
532
    }
533
534
    /**
535
     * @expectedException \Mockery\Exception
536
     */
537
    public function testMockingMultipleInterfacesThrowsExceptionWhenGivenNonExistingClassOrInterface()
538
    {
539
        $m = $this->container->mock('DoesNotExist, MockeryTest_Interface2');
540
        $this->assertTrue($m instanceof MockeryTest_Interface1);
541
        $this->assertTrue($m instanceof MockeryTest_Interface2);
542
    }
543
544
    /**
545
     * @group issue/15
546
     */
547
    public function testCanMockClassAndApplyMultipleInterfaces()
548
    {
549
        $m = $this->container->mock('MockeryTestFoo, MockeryTest_Interface1, MockeryTest_Interface2');
550
        $this->assertTrue($m instanceof MockeryTestFoo);
551
        $this->assertTrue($m instanceof MockeryTest_Interface1);
552
        $this->assertTrue($m instanceof MockeryTest_Interface2);
553
    }
554
555
    /**
556
     * @group issue/7
557
     *
558
     * Noted: We could complicate internally, but a blind class is better built
559
     * with a real class noted up front (stdClass is a perfect choice it is
560
     * behaviourless). Fine, it's a muddle - but we need to draw a line somewhere.
561
     */
562
    public function testCanMockStaticMethods()
563
    {
564
        Mockery::setContainer($this->container);
565
        $m = $this->container->mock('alias:MyNamespace\MyClass2');
566
        $m->shouldReceive('staticFoo')->andReturn('bar');
567
        $this->assertEquals('bar', \MyNameSpace\MyClass2::staticFoo());
568
        Mockery::resetContainer();
569
    }
570
571
    /**
572
     * @group issue/7
573
     * @expectedException \Mockery\CountValidator\Exception
574
     */
575
    public function testMockedStaticMethodsObeyMethodCounting()
576
    {
577
        Mockery::setContainer($this->container);
578
        $m = $this->container->mock('alias:MyNamespace\MyClass3');
579
        $m->shouldReceive('staticFoo')->once()->andReturn('bar');
580
        $this->container->mockery_verify();
581
        Mockery::resetContainer();
582
    }
583
584
    /**
585
     * @expectedException BadMethodCallException
586
     */
587
    public function testMockedStaticThrowsExceptionWhenMethodDoesNotExist()
588
    {
589
        Mockery::setContainer($this->container);
590
        $m = $this->container->mock('alias:MyNamespace\StaticNoMethod');
591
        $this->assertEquals('bar', MyNameSpace\StaticNoMethod::staticFoo());
592
        Mockery::resetContainer();
593
    }
594
595
    /**
596
     * @group issue/17
597
     */
598
    public function testMockingAllowsPublicPropertyStubbingOnRealClass()
599
    {
600
        $m = $this->container->mock('MockeryTestFoo');
601
        $m->foo = 'bar';
602
        $this->assertEquals('bar', $m->foo);
603
        //$this->assertTrue(array_key_exists('foo', $m->mockery_getMockableProperties()));
604
    }
605
606
    /**
607
     * @group issue/17
608
     */
609
    public function testMockingAllowsPublicPropertyStubbingOnNamedMock()
610
    {
611
        $m = $this->container->mock('Foo');
612
        $m->foo = 'bar';
613
        $this->assertEquals('bar', $m->foo);
614
        //$this->assertTrue(array_key_exists('foo', $m->mockery_getMockableProperties()));
615
    }
616
617
    /**
618
     * @group issue/17
619
     */
620
    public function testMockingAllowsPublicPropertyStubbingOnPartials()
621
    {
622
        $m = $this->container->mock(new stdClass);
623
        $m->foo = 'bar';
624
        $this->assertEquals('bar', $m->foo);
625
        //$this->assertTrue(array_key_exists('foo', $m->mockery_getMockableProperties()));
626
    }
627
628
    /**
629
     * @group issue/17
630
     */
631
    public function testMockingDoesNotStubNonStubbedPropertiesOnPartials()
632
    {
633
        $m = $this->container->mock(new MockeryTest_ExistingProperty);
634
        $this->assertEquals('bar', $m->foo);
635
        $this->assertFalse(array_key_exists('foo', $m->mockery_getMockableProperties()));
636
    }
637
638
    public function testCreationOfInstanceMock()
639
    {
640
        $m = $this->container->mock('overload:MyNamespace\MyClass4');
641
        $this->assertTrue($m instanceof MyNamespace\MyClass4);
642
    }
643
644
    public function testInstantiationOfInstanceMock()
645
    {
646
        Mockery::setContainer($this->container);
647
        $m = $this->container->mock('overload:MyNamespace\MyClass5');
648
        $instance = new MyNamespace\MyClass5;
649
        $this->assertTrue($instance instanceof MyNamespace\MyClass5);
650
        Mockery::resetContainer();
651
    }
652
653
    public function testInstantiationOfInstanceMockImportsExpectations()
654
    {
655
        Mockery::setContainer($this->container);
656
        $m = $this->container->mock('overload:MyNamespace\MyClass6');
657
        $m->shouldReceive('foo')->andReturn('bar');
658
        $instance = new MyNamespace\MyClass6;
659
        $this->assertEquals('bar', $instance->foo());
660
        Mockery::resetContainer();
661
    }
662
663
    public function testInstantiationOfInstanceMocksIgnoresVerificationOfOriginMock()
664
    {
665
        Mockery::setContainer($this->container);
666
        $m = $this->container->mock('overload:MyNamespace\MyClass7');
667
        $m->shouldReceive('foo')->once()->andReturn('bar');
668
        $this->container->mockery_verify();
669
        Mockery::resetContainer(); //should not throw an exception
670
    }
671
672
    /**
673
     * @expectedException \Mockery\CountValidator\Exception
674
     */
675
    public function testInstantiationOfInstanceMocksAddsThemToContainerForVerification()
676
    {
677
        Mockery::setContainer($this->container);
678
        $m = $this->container->mock('overload:MyNamespace\MyClass8');
679
        $m->shouldReceive('foo')->once();
680
        $instance = new MyNamespace\MyClass8;
681
        $this->container->mockery_verify();
682
        Mockery::resetContainer();
683
    }
684
685
    public function testInstantiationOfInstanceMocksDoesNotHaveCountValidatorCrossover()
686
    {
687
        Mockery::setContainer($this->container);
688
        $m = $this->container->mock('overload:MyNamespace\MyClass9');
689
        $m->shouldReceive('foo')->once();
690
        $instance1 = new MyNamespace\MyClass9;
691
        $instance2 = new MyNamespace\MyClass9;
692
        $instance1->foo();
693
        $instance2->foo();
694
        $this->container->mockery_verify();
695
        Mockery::resetContainer();
696
    }
697
698
    /**
699
     * @expectedException \Mockery\CountValidator\Exception
700
     */
701
    public function testInstantiationOfInstanceMocksDoesNotHaveCountValidatorCrossover2()
702
    {
703
        Mockery::setContainer($this->container);
704
        $m = $this->container->mock('overload:MyNamespace\MyClass10');
705
        $m->shouldReceive('foo')->once();
706
        $instance1 = new MyNamespace\MyClass10;
707
        $instance2 = new MyNamespace\MyClass10;
708
        $instance1->foo();
709
        $this->container->mockery_verify();
710
        Mockery::resetContainer();
711
    }
712
713
    public function testCreationOfInstanceMockWithFullyQualifiedName()
714
    {
715
        $m = $this->container->mock('overload:\MyNamespace\MyClass11');
716
        $this->assertTrue($m instanceof MyNamespace\MyClass11);
717
    }
718
719
    public function testInstanceMocksShouldIgnoreMissing()
720
    {
721
        Mockery::setContainer($this->container);
722
        $m = $this->container->mock('overload:MyNamespace\MyClass12');
723
        $m->shouldIgnoreMissing();
724
725
        $instance = new MyNamespace\MyClass12();
726
        $instance->foo();
727
728
        Mockery::resetContainer();
729
    }
730
731
    public function testMethodParamsPassedByReferenceHaveReferencePreserved()
732
    {
733
        $m = $this->container->mock('MockeryTestRef1');
734
        $m->shouldReceive('foo')->with(
735
            Mockery::on(function (&$a) {$a += 1;return true;}),
736
            Mockery::any()
737
        );
738
        $a = 1;
739
        $b = 1;
740
        $m->foo($a, $b);
741
        $this->assertEquals(2, $a);
742
        $this->assertEquals(1, $b);
743
    }
744
745
    /**
746
     * Meant to test the same logic as
747
     * testCanOverrideExpectedParametersOfExtensionPHPClassesToPreserveRefs,
748
     * but:
749
     * - doesn't require an extension
750
     * - isn't actually known to be used
751
     */
752
    public function testCanOverrideExpectedParametersOfInternalPHPClassesToPreserveRefs()
753
    {
754
        Mockery::getConfiguration()->setInternalClassMethodParamMap(
755
            'DateTime', 'modify', array('&$string')
756
        );
757
        // @ used to avoid E_STRICT for incompatible signature
758
        @$m = $this->container->mock('DateTime');
759
        $this->assertInstanceOf("Mockery\MockInterface", $m, "Mocking failed, remove @ error suppresion to debug");
760
        $m->shouldReceive('modify')->with(
761
            Mockery::on(function (&$string) {$string = 'foo'; return true;})
762
        );
763
        $data ='bar';
764
        $m->modify($data);
765
        $this->assertEquals('foo', $data);
766
        $this->container->mockery_verify();
767
        Mockery::resetContainer();
768
        Mockery::getConfiguration()->resetInternalClassMethodParamMaps();
769
    }
770
771
    /**
772
     * Real world version of
773
     * testCanOverrideExpectedParametersOfInternalPHPClassesToPreserveRefs
774
     */
775
    public function testCanOverrideExpectedParametersOfExtensionPHPClassesToPreserveRefs()
776
    {
777
        if (!class_exists('MongoCollection', false)) {
778
            $this->markTestSkipped('ext/mongo not installed');
779
        }
780
        Mockery::getConfiguration()->setInternalClassMethodParamMap(
781
            'MongoCollection', 'insert', array('&$data', '$options')
782
        );
783
        // @ used to avoid E_STRICT for incompatible signature
784
        @$m = $this->container->mock('MongoCollection');
785
        $this->assertInstanceOf("Mockery\MockInterface", $m, "Mocking failed, remove @ error suppresion to debug");
786
        $m->shouldReceive('insert')->with(
787
            Mockery::on(function (&$data) {$data['_id'] = 123; return true;}),
788
            Mockery::type('array')
789
        );
790
        $data = array('a'=>1,'b'=>2);
791
        $m->insert($data, array());
792
        $this->assertTrue(isset($data['_id']));
793
        $this->assertEquals(123, $data['_id']);
794
        $this->container->mockery_verify();
795
        Mockery::resetContainer();
796
        Mockery::getConfiguration()->resetInternalClassMethodParamMaps();
797
    }
798
799
    public function testCanCreateNonOverridenInstanceOfPreviouslyOverridenInternalClasses()
800
    {
801
        Mockery::getConfiguration()->setInternalClassMethodParamMap(
802
            'DateTime', 'modify', array('&$string')
803
        );
804
        // @ used to avoid E_STRICT for incompatible signature
805
        @$m = $this->container->mock('DateTime');
806
        $this->assertInstanceOf("Mockery\MockInterface", $m, "Mocking failed, remove @ error suppresion to debug");
807
        $rc = new ReflectionClass($m);
808
        $rm = $rc->getMethod('modify');
809
        $params = $rm->getParameters();
810
        $this->assertTrue($params[0]->isPassedByReference());
811
812
        Mockery::getConfiguration()->resetInternalClassMethodParamMaps();
813
814
        $m = $this->container->mock('DateTime');
815
        $this->assertInstanceOf("Mockery\MockInterface", $m, "Mocking failed");
816
        $rc = new ReflectionClass($m);
817
        $rm = $rc->getMethod('modify');
818
        $params = $rm->getParameters();
819
        $this->assertFalse($params[0]->isPassedByReference());
820
821
        Mockery::resetContainer();
822
        Mockery::getConfiguration()->resetInternalClassMethodParamMaps();
823
    }
824
825
    /**
826
     * @group abstract
827
     */
828
    public function testCanMockAbstractClassWithAbstractPublicMethod()
829
    {
830
        $m = $this->container->mock('MockeryTest_AbstractWithAbstractPublicMethod');
831
        $this->assertTrue($m instanceof MockeryTest_AbstractWithAbstractPublicMethod);
832
    }
833
834
    /**
835
     * @issue issue/21
836
     */
837
    public function testClassDeclaringIssetDoesNotThrowException()
838
    {
839
        Mockery::setContainer($this->container);
840
        $m = $this->container->mock('MockeryTest_IssetMethod');
841
        $this->container->mockery_verify();
842
        Mockery::resetContainer();
843
    }
844
845
    /**
846
     * @issue issue/21
847
     */
848
    public function testClassDeclaringUnsetDoesNotThrowException()
849
    {
850
        Mockery::setContainer($this->container);
851
        $m = $this->container->mock('MockeryTest_UnsetMethod');
852
        $this->container->mockery_verify();
853
        Mockery::resetContainer();
854
    }
855
856
    /**
857
     * @issue issue/35
858
     */
859
    public function testCallingSelfOnlyReturnsLastMockCreatedOrCurrentMockBeingProgrammedSinceTheyAreOneAndTheSame()
860
    {
861
        Mockery::setContainer($this->container);
862
        $m = $this->container->mock('MockeryTestFoo');
863
        $this->assertFalse($this->container->self() instanceof MockeryTestFoo2);
864
        //$m = $this->container->mock('MockeryTestFoo2');
865
        //$this->assertTrue($this->container->self() instanceof MockeryTestFoo2);
866
        //$m = $this->container->mock('MockeryTestFoo');
867
        //$this->assertFalse(Mockery::self() instanceof MockeryTestFoo2);
868
        //$this->assertTrue(Mockery::self() instanceof MockeryTestFoo);
869
        Mockery::resetContainer();
870
    }
871
872
    /**
873
     * @issue issue/89
874
     */
875
    public function testCreatingMockOfClassWithExistingToStringMethodDoesntCreateClassWithTwoToStringMethods()
876
    {
877
        Mockery::setContainer($this->container);
878
        $m = $this->container->mock('MockeryTest_WithToString'); // this would fatal
879
        $m->shouldReceive("__toString")->andReturn('dave');
880
        $this->assertEquals("dave", "$m");
881
    }
882
883
    public function testGetExpectationCount_freshContainer()
884
    {
885
        $this->assertEquals(0, $this->container->mockery_getExpectationCount());
886
    }
887
888
    public function testGetExpectationCount_simplestMock()
889
    {
890
        $m = $this->container->mock();
891
        $m->shouldReceive('foo')->andReturn('bar');
892
        $this->assertEquals(1, $this->container->mockery_getExpectationCount());
893
    }
894
895
    public function testMethodsReturningParamsByReferenceDoesNotErrorOut()
896
    {
897
        $this->container->mock('MockeryTest_ReturnByRef');
898
        $mock = $this->container->mock('MockeryTest_ReturnByRef');
899
        $mock->shouldReceive("get")->andReturn($var = 123);
900
        $this->assertSame($var, $mock->get());
901
    }
902
903
    public function testMockCallableTypeHint()
904
    {
905
        if (PHP_VERSION_ID >= 50400) {
906
            $this->container->mock('MockeryTest_MockCallableTypeHint');
907
        }
908
    }
909
910
    public function testCanMockClassWithReservedWordMethod()
911
    {
912
        if (!extension_loaded("redis")) {
913
            $this->markTestSkipped("phpredis not installed");
914
        }
915
916
        $this->container->mock("Redis");
917
    }
918
919
    public function testUndeclaredClassIsDeclared()
920
    {
921
        $this->assertFalse(class_exists("BlahBlah"));
922
        $mock = $this->container->mock("BlahBlah");
923
        $this->assertInstanceOf("BlahBlah", $mock);
924
    }
925
926
    public function testUndeclaredClassWithNamespaceIsDeclared()
927
    {
928
        $this->assertFalse(class_exists("MyClasses\Blah\BlahBlah"));
929
        $mock = $this->container->mock("MyClasses\Blah\BlahBlah");
930
        $this->assertInstanceOf("MyClasses\Blah\BlahBlah", $mock);
931
    }
932
933
    public function testUndeclaredClassWithNamespaceIncludingLeadingOperatorIsDeclared()
934
    {
935
        $this->assertFalse(class_exists("\MyClasses\DaveBlah\BlahBlah"));
936
        $mock = $this->container->mock("\MyClasses\DaveBlah\BlahBlah");
937
        $this->assertInstanceOf("\MyClasses\DaveBlah\BlahBlah", $mock);
938
    }
939
940
    public function testMockingPhpredisExtensionClassWorks()
941
    {
942
        if (!class_exists('Redis')) {
943
            $this->markTestSkipped('PHPRedis extension required for this test');
944
        }
945
        $m = $this->container->mock('Redis');
946
    }
947
948
    public function testIssetMappingUsingProxiedPartials_CheckNoExceptionThrown()
949
    {
950
        $var = $this->container->mock(new MockeryTestIsset_Bar());
951
        $mock = $this->container->mock(new MockeryTestIsset_Foo($var));
952
        $mock->shouldReceive('bar')->once();
953
        $mock->bar();
954
        $this->container->mockery_teardown(); // closed by teardown()
955
    }
956
957
    /**
958
     * @group traversable1
959
     */
960
    public function testCanMockInterfacesExtendingTraversable()
961
    {
962
        $mock = $this->container->mock('MockeryTest_InterfaceWithTraversable');
963
        $this->assertInstanceOf('MockeryTest_InterfaceWithTraversable', $mock);
964
        $this->assertInstanceOf('ArrayAccess', $mock);
965
        $this->assertInstanceOf('Countable', $mock);
966
        $this->assertInstanceOf('Traversable', $mock);
967
    }
968
969
    /**
970
     * @group traversable2
971
     */
972
    public function testCanMockInterfacesAlongsideTraversable()
973
    {
974
        $mock = $this->container->mock('stdClass, ArrayAccess, Countable, Traversable');
975
        $this->assertInstanceOf('stdClass', $mock);
976
        $this->assertInstanceOf('ArrayAccess', $mock);
977
        $this->assertInstanceOf('Countable', $mock);
978
        $this->assertInstanceOf('Traversable', $mock);
979
    }
980
981
    public function testInterfacesCanHaveAssertions()
982
    {
983
        Mockery::setContainer($this->container);
984
        $m = $this->container->mock('stdClass, ArrayAccess, Countable, Traversable');
985
        $m->shouldReceive('foo')->once();
986
        $m->foo();
987
        $this->container->mockery_verify();
988
        Mockery::resetContainer();
989
    }
990
991
    public function testMockingIteratorAggregateDoesNotImplementIterator()
992
    {
993
        $mock = $this->container->mock('MockeryTest_ImplementsIteratorAggregate');
994
        $this->assertInstanceOf('IteratorAggregate', $mock);
995
        $this->assertInstanceOf('Traversable', $mock);
996
        $this->assertNotInstanceOf('Iterator', $mock);
997
    }
998
999
    public function testMockingInterfaceThatExtendsIteratorDoesNotImplementIterator()
1000
    {
1001
        $mock = $this->container->mock('MockeryTest_InterfaceThatExtendsIterator');
1002
        $this->assertInstanceOf('Iterator', $mock);
1003
        $this->assertInstanceOf('Traversable', $mock);
1004
    }
1005
1006
    public function testMockingInterfaceThatExtendsIteratorAggregateDoesNotImplementIterator()
1007
    {
1008
        $mock = $this->container->mock('MockeryTest_InterfaceThatExtendsIteratorAggregate');
1009
        $this->assertInstanceOf('IteratorAggregate', $mock);
1010
        $this->assertInstanceOf('Traversable', $mock);
1011
        $this->assertNotInstanceOf('Iterator', $mock);
1012
    }
1013
1014
    public function testMockingIteratorAggregateDoesNotImplementIteratorAlongside()
1015
    {
1016
        $mock = $this->container->mock('IteratorAggregate');
1017
        $this->assertInstanceOf('IteratorAggregate', $mock);
1018
        $this->assertInstanceOf('Traversable', $mock);
1019
        $this->assertNotInstanceOf('Iterator', $mock);
1020
    }
1021
1022
    public function testMockingIteratorDoesNotImplementIteratorAlongside()
1023
    {
1024
        $mock = $this->container->mock('Iterator');
1025
        $this->assertInstanceOf('Iterator', $mock);
1026
        $this->assertInstanceOf('Traversable', $mock);
1027
    }
1028
1029
    public function testMockingIteratorDoesNotImplementIterator()
1030
    {
1031
        $mock = $this->container->mock('MockeryTest_ImplementsIterator');
1032
        $this->assertInstanceOf('Iterator', $mock);
1033
        $this->assertInstanceOf('Traversable', $mock);
1034
    }
1035
1036
    public function testMockeryCloseForIllegalIssetFileInclude()
1037
    {
1038
        $m = Mockery::mock('StdClass')
1039
            ->shouldReceive('get')
1040
            ->andReturn(false)
1041
            ->getMock();
1042
        $m->get();
1043
        Mockery::close();
1044
    }
1045
1046
    public function testMockeryShouldDistinguishBetweenConstructorParamsAndClosures()
1047
    {
1048
        $obj = new MockeryTestFoo();
1049
        $mock = $this->container->mock('MockeryTest_ClassMultipleConstructorParams[dave]',
1050
            array( &$obj, 'foo' ));
1051
    }
1052
1053
    /** @group nette */
1054
    public function testMockeryShouldNotMockCallstaticMagicMethod()
1055
    {
1056
        $mock = $this->container->mock('MockeryTest_CallStatic');
1057
    }
1058
1059
    /**
1060
     * @issue issue/139
1061
     */
1062
    public function testCanMockClassWithOldStyleConstructorAndArguments()
1063
    {
1064
        $mock = $this->container->mock('MockeryTest_OldStyleConstructor');
1065
    }
1066
1067
    /** @group issue/144 */
1068
    public function testMockeryShouldInterpretEmptyArrayAsConstructorArgs()
1069
    {
1070
        $mock = $this->container->mock("EmptyConstructorTest", array());
1071
        $this->assertSame(0, $mock->numberOfConstructorArgs);
1072
    }
1073
1074
    /** @group issue/144 */
1075
    public function testMockeryShouldCallConstructorByDefaultWhenRequestingPartials()
1076
    {
1077
        $mock = $this->container->mock("EmptyConstructorTest[foo]");
1078
        $this->assertSame(0, $mock->numberOfConstructorArgs);
1079
    }
1080
1081
    /** @group issue/158 */
1082
    public function testMockeryShouldRespectInterfaceWithMethodParamSelf()
1083
    {
1084
        $this->container->mock('MockeryTest_InterfaceWithMethodParamSelf');
1085
    }
1086
1087
    /** @group issue/162 */
1088
    public function testMockeryDoesntTryAndMockLowercaseToString()
1089
    {
1090
        $this->container->mock('MockeryTest_Lowercase_ToString');
1091
    }
1092
1093
    /** @group issue/175 */
1094
    public function testExistingStaticMethodMocking()
1095
    {
1096
        Mockery::setContainer($this->container);
1097
        $mock = $this->container->mock('MockeryTest_PartialStatic[mockMe]');
1098
1099
        $mock->shouldReceive('mockMe')->with(5)->andReturn(10);
1100
1101
        $this->assertEquals(10, $mock::mockMe(5));
1102
        $this->assertEquals(3, $mock::keepMe(3));
1103
    }
1104
1105
    /**
1106
     * @group issue/154
1107
     * @expectedException InvalidArgumentException
1108
     * @expectedExceptionMessage protectedMethod() cannot be mocked as it a protected method and mocking protected methods is not allowed for this mock
1109
     */
1110
    public function testShouldThrowIfAttemptingToStubProtectedMethod()
1111
    {
1112
        $mock = $this->container->mock('MockeryTest_WithProtectedAndPrivate');
1113
        $mock->shouldReceive("protectedMethod");
1114
    }
1115
1116
    /**
1117
     * @group issue/154
1118
     * @expectedException InvalidArgumentException
1119
     * @expectedExceptionMessage privateMethod() cannot be mocked as it is a private method
1120
     */
1121
    public function testShouldThrowIfAttemptingToStubPrivateMethod()
1122
    {
1123
        $mock = $this->container->mock('MockeryTest_WithProtectedAndPrivate');
1124
        $mock->shouldReceive("privateMethod");
1125
    }
1126
1127
    public function testWakeupMagicIsNotMockedToAllowSerialisationInstanceHack()
1128
    {
1129
        $mock = $this->container->mock('DateTime');
1130
    }
1131
1132
    /**
1133
     * @group issue/154
1134
     */
1135
    public function testCanMockMethodsWithRequiredParamsThatHaveDefaultValues()
1136
    {
1137
        $mock = $this->container->mock('MockeryTest_MethodWithRequiredParamWithDefaultValue');
1138
        $mock->shouldIgnoreMissing();
1139
        $mock->foo(null, 123);
1140
    }
1141
1142
    /**
1143
     * @test
1144
     * @group issue/294
1145
     * @expectedException Mockery\Exception\RuntimeException
1146
     * @expectedExceptionMessage Could not load mock DateTime, class already exists
1147
     */
1148
    public function testThrowsWhenNamedMockClassExistsAndIsNotMockery()
1149
    {
1150
        $builder = new MockConfigurationBuilder();
1151
        $builder->setName("DateTime");
1152
        $mock = $this->container->mock($builder);
1153
    }
1154
1155
    /**
1156
     * @expectedException Mockery\Exception\NoMatchingExpectationException
1157
     * @expectedExceptionMessage MyTestClass::foo(resource(...))
1158
     */
1159
    public function testHandlesMethodWithArgumentExpectationWhenCalledWithResource()
1160
    {
1161
        $mock = $this->container->mock('MyTestClass');
1162
        $mock->shouldReceive('foo')->with(array('yourself' => 21));
1163
1164
        $mock->foo(fopen('php://memory', 'r'));
1165
    }
1166
1167
    /**
1168
     * @expectedException Mockery\Exception\NoMatchingExpectationException
1169
     * @expectedExceptionMessage MyTestClass::foo(array('myself'=>'array(...)',))
1170
     */
1171
    public function testHandlesMethodWithArgumentExpectationWhenCalledWithCircularArray()
1172
    {
1173
        $testArray = array();
1174
        $testArray['myself'] =& $testArray;
1175
1176
        $mock = $this->container->mock('MyTestClass');
1177
        $mock->shouldReceive('foo')->with(array('yourself' => 21));
1178
1179
        $mock->foo($testArray);
1180
    }
1181
1182
    /**
1183
     * @expectedException Mockery\Exception\NoMatchingExpectationException
1184
     * @expectedExceptionMessage MyTestClass::foo(array('a_scalar'=>2,'an_array'=>'array(...)',))
1185
     */
1186
    public function testHandlesMethodWithArgumentExpectationWhenCalledWithNestedArray()
1187
    {
1188
        $testArray = array();
1189
        $testArray['a_scalar'] = 2;
1190
        $testArray['an_array'] = array(1, 2, 3);
1191
1192
        $mock = $this->container->mock('MyTestClass');
1193
        $mock->shouldReceive('foo')->with(array('yourself' => 21));
1194
1195
        $mock->foo($testArray);
1196
    }
1197
1198
    /**
1199
     * @expectedException Mockery\Exception\NoMatchingExpectationException
1200
     * @expectedExceptionMessage MyTestClass::foo(array('a_scalar'=>2,'an_object'=>'object(stdClass)',))
1201
     */
1202
    public function testHandlesMethodWithArgumentExpectationWhenCalledWithNestedObject()
1203
    {
1204
        $testArray = array();
1205
        $testArray['a_scalar'] = 2;
1206
        $testArray['an_object'] = new stdClass();
1207
1208
        $mock = $this->container->mock('MyTestClass');
1209
        $mock->shouldReceive('foo')->with(array('yourself' => 21));
1210
1211
        $mock->foo($testArray);
1212
    }
1213
1214
    /**
1215
     * @expectedException Mockery\Exception\NoMatchingExpectationException
1216
     * @expectedExceptionMessage MyTestClass::foo(array('a_scalar'=>2,'a_closure'=>'object(Closure
1217
     */
1218
    public function testHandlesMethodWithArgumentExpectationWhenCalledWithNestedClosure()
1219
    {
1220
        $testArray = array();
1221
        $testArray['a_scalar'] = 2;
1222
        $testArray['a_closure'] = function () {
1223
        };
1224
1225
        $mock = $this->container->mock('MyTestClass');
1226
        $mock->shouldReceive('foo')->with(array('yourself' => 21));
1227
1228
        $mock->foo($testArray);
1229
    }
1230
1231
    /**
1232
     * @expectedException Mockery\Exception\NoMatchingExpectationException
1233
     * @expectedExceptionMessage MyTestClass::foo(array('a_scalar'=>2,'a_resource'=>'resource(...)',))
1234
     */
1235
    public function testHandlesMethodWithArgumentExpectationWhenCalledWithNestedResource()
1236
    {
1237
        $testArray = array();
1238
        $testArray['a_scalar'] = 2;
1239
        $testArray['a_resource'] = fopen('php://memory', 'r');
1240
1241
        $mock = $this->container->mock('MyTestClass');
1242
        $mock->shouldReceive('foo')->with(array('yourself' => 21));
1243
1244
        $mock->foo($testArray);
1245
    }
1246
1247
    /**
1248
     * @test
1249
     * @group issue/339
1250
     */
1251
    public function canMockClassesThatDescendFromInternalClasses()
1252
    {
1253
        $mock = $this->container->mock("MockeryTest_ClassThatDescendsFromInternalClass");
1254
        $this->assertInstanceOf("DateTime", $mock);
1255
    }
1256
1257
    /**
1258
     * @test
1259
     * @group issue/339
1260
     */
1261
    public function canMockClassesThatImplementSerializable()
1262
    {
1263
        $mock = $this->container->mock("MockeryTest_ClassThatImplementsSerializable");
1264
        $this->assertInstanceOf("Serializable", $mock);
1265
    }
1266
1267
    /**
1268
     * @test
1269
     * @group issue/346
1270
     */
1271
    public function canMockInternalClassesThatImplementSerializable()
1272
    {
1273
        $mock = $this->container->mock("ArrayObject");
1274
        $this->assertInstanceOf("Serializable", $mock);
1275
    }
1276
}
1277
1278
class MockeryTest_CallStatic
1279
{
1280
    public static function __callStatic($method, $args)
1281
    {
1282
    }
1283
}
1284
1285
class MockeryTest_ClassMultipleConstructorParams
1286
{
1287
    public function __construct($a, $b)
1288
    {
1289
    }
1290
1291
    public function dave()
1292
    {
1293
    }
1294
}
1295
1296
interface MockeryTest_InterfaceWithTraversable extends ArrayAccess, Traversable, Countable
1297
{
1298
    public function self();
1299
}
1300
1301
class MockeryTestIsset_Bar
1302
{
1303
    public function doSomething()
1304
    {
1305
    }
1306
}
1307
1308
class MockeryTestIsset_Foo
1309
{
1310
    private $var;
1311
1312
    public function __construct($var)
1313
    {
1314
        $this->var = $var;
1315
    }
1316
1317
    public function __get($name)
1318
    {
1319
        $this->var->doSomething();
1320
    }
1321
1322
    public function __isset($name)
1323
    {
1324
        return (bool) strlen($this->__get($name));
1325
    }
1326
}
1327
1328
class MockeryTest_IssetMethod
1329
{
1330
    protected $_properties = array();
1331
1332
    public function __construct()
1333
    {
1334
    }
1335
1336
    public function __isset($property)
1337
    {
1338
        return isset($this->_properties[$property]);
1339
    }
1340
}
1341
1342
class MockeryTest_UnsetMethod
1343
{
1344
    protected $_properties = array();
1345
1346
    public function __construct()
1347
    {
1348
    }
1349
1350
    public function __unset($property)
1351
    {
1352
        unset($this->_properties[$property]);
1353
    }
1354
}
1355
1356
class MockeryTestFoo
1357
{
1358
    public function foo()
1359
    {
1360
        return 'foo';
1361
    }
1362
}
1363
1364
class MockeryTestFoo2
1365
{
1366
    public function foo()
1367
    {
1368
        return 'foo';
1369
    }
1370
1371
    public function bar()
1372
    {
1373
        return 'bar';
1374
    }
1375
}
1376
1377
final class MockeryFoo3
1378
{
1379
    public function foo()
1380
    {
1381
        return 'baz';
1382
    }
1383
}
1384
1385
class MockeryFoo4
1386
{
1387
    final public function foo()
1388
    {
1389
        return 'baz';
1390
    }
1391
1392
    public function bar()
1393
    {
1394
        return 'bar';
1395
    }
1396
}
1397
1398
interface MockeryTest_Interface
1399
{
1400
}
1401
interface MockeryTest_Interface1
1402
{
1403
}
1404
interface MockeryTest_Interface2
1405
{
1406
}
1407
1408
interface MockeryTest_InterfaceWithAbstractMethod
1409
{
1410
    public function set();
1411
}
1412
1413
interface MockeryTest_InterfaceWithPublicStaticMethod
1414
{
1415
    public static function self();
1416
}
1417
1418
abstract class MockeryTest_AbstractWithAbstractMethod
1419
{
1420
    abstract protected function set();
1421
}
1422
1423
class MockeryTest_WithProtectedAndPrivate
1424
{
1425
    protected function protectedMethod()
1426
    {
1427
    }
1428
1429
    private function privateMethod()
1430
    {
1431
    }
1432
}
1433
1434
class MockeryTest_ClassConstructor
1435
{
1436
    public function __construct($param1)
1437
    {
1438
    }
1439
}
1440
1441
class MockeryTest_ClassConstructor2
1442
{
1443
    protected $param1;
1444
1445
    public function __construct(stdClass $param1)
1446
    {
1447
        $this->param1 = $param1;
1448
    }
1449
1450
    public function getParam1()
1451
    {
1452
        return $this->param1;
1453
    }
1454
1455
    public function foo()
1456
    {
1457
        return 'foo';
1458
    }
1459
1460
    public function bar()
1461
    {
1462
        return $this->foo();
1463
    }
1464
}
1465
1466
class MockeryTest_Call1
1467
{
1468
    public function __call($method, array $params)
1469
    {
1470
    }
1471
}
1472
1473
class MockeryTest_Call2
1474
{
1475
    public function __call($method, $params)
1476
    {
1477
    }
1478
}
1479
1480
class MockeryTest_Wakeup1
1481
{
1482
    public function __construct()
1483
    {
1484
    }
1485
1486
    public function __wakeup()
1487
    {
1488
    }
1489
}
1490
1491
class MockeryTest_ExistingProperty
1492
{
1493
    public $foo = 'bar';
1494
}
1495
1496
abstract class MockeryTest_AbstractWithAbstractPublicMethod
1497
{
1498
    abstract public function foo($a, $b);
1499
}
1500
1501
// issue/18
1502
class SoCool
1503
{
1504
    public function iDoSomethingReallyCoolHere()
1505
    {
1506
        return 3;
1507
    }
1508
}
1509
1510
class Gateway
1511
{
1512
    public function __call($method, $args)
1513
    {
1514
        $m = new SoCool();
1515
        return call_user_func_array(array($m, $method), $args);
1516
    }
1517
}
1518
1519
class MockeryTestBar1
1520
{
1521
    public function method1()
1522
    {
1523
        return $this;
1524
    }
1525
}
1526
1527
class MockeryTest_ReturnByRef
1528
{
1529
    public $i = 0;
1530
1531
    public function &get()
1532
    {
1533
        return $this->$i;
1534
    }
1535
}
1536
1537
class MockeryTest_MethodParamRef
1538
{
1539
    public function method1(&$foo)
1540
    {
1541
        return true;
1542
    }
1543
}
1544
class MockeryTest_MethodParamRef2
1545
{
1546
    public function method1(&$foo)
1547
    {
1548
        return true;
1549
    }
1550
}
1551
class MockeryTestRef1
1552
{
1553
    public function foo(&$a, $b)
1554
    {
1555
    }
1556
}
1557
1558
class MockeryTest_PartialNormalClass
1559
{
1560
    public function foo()
1561
    {
1562
        return 'abc';
1563
    }
1564
1565
    public function bar()
1566
    {
1567
        return 'abc';
1568
    }
1569
}
1570
1571
abstract class MockeryTest_PartialAbstractClass
1572
{
1573
    abstract public function foo();
1574
1575
    public function bar()
1576
    {
1577
        return 'abc';
1578
    }
1579
}
1580
1581
class MockeryTest_PartialNormalClass2
1582
{
1583
    public function foo()
1584
    {
1585
        return 'abc';
1586
    }
1587
1588
    public function bar()
1589
    {
1590
        return 'abc';
1591
    }
1592
1593
    public function baz()
1594
    {
1595
        return 'abc';
1596
    }
1597
}
1598
1599
abstract class MockeryTest_PartialAbstractClass2
1600
{
1601
    abstract public function foo();
1602
1603
    public function bar()
1604
    {
1605
        return 'abc';
1606
    }
1607
1608
    abstract public function baz();
1609
}
1610
1611
class MockeryTest_TestInheritedType
1612
{
1613
}
1614
1615
if (PHP_VERSION_ID >= 50400) {
1616
    class MockeryTest_MockCallableTypeHint
1617
    {
1618
        public function foo(callable $baz)
1619
        {
1620
            $baz();
1621
        }
1622
1623
        public function bar(callable $callback = null)
1624
        {
1625
            $callback();
1626
        }
1627
    }
1628
}
1629
1630
class MockeryTest_WithToString
1631
{
1632
    public function __toString()
1633
    {
1634
    }
1635
}
1636
1637
class MockeryTest_ImplementsIteratorAggregate implements IteratorAggregate
1638
{
1639
    public function getIterator()
1640
    {
1641
        return new ArrayIterator(array());
1642
    }
1643
}
1644
1645
class MockeryTest_ImplementsIterator implements Iterator
1646
{
1647
    public function rewind()
1648
    {
1649
    }
1650
1651
    public function current()
1652
    {
1653
    }
1654
1655
    public function key()
1656
    {
1657
    }
1658
1659
    public function next()
1660
    {
1661
    }
1662
1663
    public function valid()
1664
    {
1665
    }
1666
}
1667
1668
class MockeryTest_OldStyleConstructor
1669
{
1670
    public function MockeryTest_OldStyleConstructor($arg)
1671
    {
1672
    }
1673
}
1674
1675
class EmptyConstructorTest
1676
{
1677
    public $numberOfConstructorArgs;
1678
1679
    public function __construct()
1680
    {
1681
        $this->numberOfConstructorArgs = count(func_get_args());
1682
    }
1683
1684
    public function foo()
1685
    {
1686
    }
1687
}
1688
1689
interface MockeryTest_InterfaceWithMethodParamSelf
1690
{
1691
    public function foo(self $bar);
1692
}
1693
1694
class MockeryTest_Lowercase_ToString
1695
{
1696
    public function __tostring()
1697
    {
1698
    }
1699
}
1700
1701
class MockeryTest_PartialStatic
1702
{
1703
    public static function mockMe($a)
1704
    {
1705
        return $a;
1706
    }
1707
1708
    public static function keepMe($b)
1709
    {
1710
        return $b;
1711
    }
1712
}
1713
1714
class MockeryTest_MethodWithRequiredParamWithDefaultValue
1715
{
1716
    public function foo(DateTime $bar = null, $baz)
1717
    {
1718
    }
1719
}
1720
1721
interface MockeryTest_InterfaceThatExtendsIterator extends Iterator
1722
{
1723
    public function foo();
1724
}
1725
1726
interface MockeryTest_InterfaceThatExtendsIteratorAggregate extends IteratorAggregate
1727
{
1728
    public function foo();
1729
}
1730
1731
class MockeryTest_ClassThatDescendsFromInternalClass extends DateTime
1732
{
1733
}
1734
1735
class MockeryTest_ClassThatImplementsSerializable implements Serializable
1736
{
1737
    public function serialize()
1738
    {
1739
    }
1740
1741
    public function unserialize($serialized)
1742
    {
1743
    }
1744
}
1745