MockObjectTest.php (22371B)
1 <?php 2 /** 3 * PHPUnit 4 * 5 * Copyright (c) 2010-2013, Sebastian Bergmann <sb@sebastian-bergmann.de>. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * * Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * * Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in 17 * the documentation and/or other materials provided with the 18 * distribution. 19 * 20 * * Neither the name of Sebastian Bergmann nor the names of his 21 * contributors may be used to endorse or promote products derived 22 * from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 30 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 * 37 * @package PHPUnit_MockObject 38 * @author Sebastian Bergmann <sb@sebastian-bergmann.de> 39 * @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de> 40 * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License 41 * @link http://www.phpunit.de/ 42 * @since File available since Release 3.0.0 43 */ 44 45 require_once 'PHPUnit/Framework/TestCase.php'; 46 47 require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'AbstractMockTestClass.php'; 48 require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'AnInterface.php'; 49 require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'FunctionCallback.php'; 50 require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'MethodCallback.php'; 51 require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'MethodCallbackByReference.php'; 52 require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'PartialMockTestClass.php'; 53 require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'SomeClass.php'; 54 require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'StaticMockTestClass.php'; 55 56 /** 57 * 58 * 59 * @package PHPUnit_MockObject 60 * @author Sebastian Bergmann <sb@sebastian-bergmann.de> 61 * @author Patrick Mueller <elias0@gmx.net> 62 * @author Frank Kleine <mikey@stubbles.net> 63 * @copyright 2010-2013 Sebastian Bergmann <sb@sebastian-bergmann.de> 64 * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License 65 * @version Release: @package_version@ 66 * @link http://www.phpunit.de/ 67 * @since Class available since Release 3.0.0 68 */ 69 class Framework_MockObjectTest extends PHPUnit_Framework_TestCase 70 { 71 public function testMockedMethodIsNeverCalled() 72 { 73 $mock = $this->getMock('AnInterface'); 74 $mock->expects($this->never()) 75 ->method('doSomething'); 76 } 77 78 public function testMockedMethodIsNotCalledWhenExpectsAnyWithParameter() 79 { 80 $mock = $this->getMock('SomeClass'); 81 $mock->expects($this->any()) 82 ->method('doSomethingElse') 83 ->with('someArg'); 84 } 85 86 public function testMockedMethodIsCalledAtLeastOnce() 87 { 88 $mock = $this->getMock('AnInterface'); 89 $mock->expects($this->atLeastOnce()) 90 ->method('doSomething'); 91 92 $mock->doSomething(); 93 } 94 95 public function testMockedMethodIsCalledAtLeastOnce2() 96 { 97 $mock = $this->getMock('AnInterface'); 98 $mock->expects($this->atLeastOnce()) 99 ->method('doSomething'); 100 101 $mock->doSomething(); 102 $mock->doSomething(); 103 } 104 105 public function testMockedMethodIsCalledOnce() 106 { 107 $mock = $this->getMock('AnInterface'); 108 $mock->expects($this->once()) 109 ->method('doSomething'); 110 111 $mock->doSomething(); 112 } 113 114 public function testMockedMethodIsCalledOnceWithParameter() 115 { 116 $mock = $this->getMock('SomeClass'); 117 $mock->expects($this->once()) 118 ->method('doSomethingElse') 119 ->with($this->equalTo('something')); 120 121 $mock->doSomethingElse('something'); 122 } 123 124 public function testMockedMethodIsCalledExactly() 125 { 126 $mock = $this->getMock('AnInterface'); 127 $mock->expects($this->exactly(2)) 128 ->method('doSomething'); 129 130 $mock->doSomething(); 131 $mock->doSomething(); 132 } 133 134 public function testStubbedException() 135 { 136 $mock = $this->getMock('AnInterface'); 137 $mock->expects($this->any()) 138 ->method('doSomething') 139 ->will($this->throwException(new Exception)); 140 141 try { 142 $mock->doSomething(); 143 } 144 145 catch (Exception $e) { 146 return; 147 } 148 149 $this->fail(); 150 } 151 152 public function testStubbedReturnValue() 153 { 154 $mock = $this->getMock('AnInterface'); 155 $mock->expects($this->any()) 156 ->method('doSomething') 157 ->will($this->returnValue('something')); 158 159 $this->assertEquals('something', $mock->doSomething()); 160 } 161 162 public function testStubbedReturnValueMap() 163 { 164 $map = array( 165 array('a', 'b', 'c', 'd'), 166 array('e', 'f', 'g', 'h') 167 ); 168 169 $mock = $this->getMock('AnInterface'); 170 $mock->expects($this->any()) 171 ->method('doSomething') 172 ->will($this->returnValueMap($map)); 173 174 $this->assertEquals('d', $mock->doSomething('a', 'b', 'c')); 175 $this->assertEquals('h', $mock->doSomething('e', 'f', 'g')); 176 $this->assertEquals(NULL, $mock->doSomething('foo', 'bar')); 177 } 178 179 public function testFunctionCallback() 180 { 181 $mock = $this->getMock('SomeClass', array('doSomething'), array(), '', FALSE); 182 $mock->expects($this->once()) 183 ->method('doSomething') 184 ->will($this->returnCallback('functionCallback')); 185 186 $this->assertEquals('pass', $mock->doSomething('foo', 'bar')); 187 } 188 189 public function testStaticMethodCallback() 190 { 191 $mock = $this->getMock('SomeClass', array('doSomething'), array(), '', FALSE); 192 $mock->expects($this->once()) 193 ->method('doSomething') 194 ->will($this->returnCallback(array('MethodCallback', 'staticCallback'))); 195 196 $this->assertEquals('pass', $mock->doSomething('foo', 'bar')); 197 } 198 199 public function testPublicMethodCallback() 200 { 201 $mock = $this->getMock('SomeClass', array('doSomething'), array(), '', FALSE); 202 $mock->expects($this->once()) 203 ->method('doSomething') 204 ->will($this->returnCallback(array(new MethodCallback, 'nonStaticCallback'))); 205 206 $this->assertEquals('pass', $mock->doSomething('foo', 'bar')); 207 } 208 209 public function testMockClassOnlyGeneratedOnce() 210 { 211 $mock1 = $this->getMock('AnInterface'); 212 $mock2 = $this->getMock('AnInterface'); 213 214 $this->assertEquals(get_class($mock1), get_class($mock2)); 215 } 216 217 public function testMockClassDifferentForPartialMocks() 218 { 219 $mock1 = $this->getMock('PartialMockTestClass'); 220 $mock2 = $this->getMock('PartialMockTestClass', array('doSomething')); 221 $mock3 = $this->getMock('PartialMockTestClass', array('doSomething')); 222 $mock4 = $this->getMock('PartialMockTestClass', array('doAnotherThing')); 223 $mock5 = $this->getMock('PartialMockTestClass', array('doAnotherThing')); 224 225 $this->assertNotEquals(get_class($mock1), get_class($mock2)); 226 $this->assertNotEquals(get_class($mock1), get_class($mock3)); 227 $this->assertNotEquals(get_class($mock1), get_class($mock4)); 228 $this->assertNotEquals(get_class($mock1), get_class($mock5)); 229 $this->assertEquals(get_class($mock2), get_class($mock3)); 230 $this->assertNotEquals(get_class($mock2), get_class($mock4)); 231 $this->assertNotEquals(get_class($mock2), get_class($mock5)); 232 $this->assertEquals(get_class($mock4), get_class($mock5)); 233 } 234 235 public function testMockClassStoreOverrulable() 236 { 237 $mock1 = $this->getMock('PartialMockTestClass'); 238 $mock2 = $this->getMock('PartialMockTestClass', array(), array(), 'MyMockClassNameForPartialMockTestClass1'); 239 $mock3 = $this->getMock('PartialMockTestClass'); 240 $mock4 = $this->getMock('PartialMockTestClass', array('doSomething'), array(), 'AnotherMockClassNameForPartialMockTestClass'); 241 $mock5 = $this->getMock('PartialMockTestClass', array(), array(), 'MyMockClassNameForPartialMockTestClass2'); 242 243 $this->assertNotEquals(get_class($mock1), get_class($mock2)); 244 $this->assertEquals(get_class($mock1), get_class($mock3)); 245 $this->assertNotEquals(get_class($mock1), get_class($mock4)); 246 $this->assertNotEquals(get_class($mock2), get_class($mock3)); 247 $this->assertNotEquals(get_class($mock2), get_class($mock4)); 248 $this->assertNotEquals(get_class($mock2), get_class($mock5)); 249 $this->assertNotEquals(get_class($mock3), get_class($mock4)); 250 $this->assertNotEquals(get_class($mock3), get_class($mock5)); 251 $this->assertNotEquals(get_class($mock4), get_class($mock5)); 252 } 253 254 /** 255 * @covers PHPUnit_Framework_MockObject_Generator::getMock 256 */ 257 public function testGetMockWithFixedClassNameCanProduceTheSameMockTwice() 258 { 259 $mock = $this->getMockBuilder('StdClass')->setMockClassName('FixedName')->getMock(); 260 $mock = $this->getMockBuilder('StdClass')->setMockClassName('FixedName')->getMock(); 261 $this->assertInstanceOf('StdClass', $mock); 262 } 263 264 public function testOriginalConstructorSettingConsidered() 265 { 266 $mock1 = $this->getMock('PartialMockTestClass'); 267 $mock2 = $this->getMock('PartialMockTestClass', array(), array(), '', FALSE); 268 269 $this->assertTrue($mock1->constructorCalled); 270 $this->assertFalse($mock2->constructorCalled); 271 } 272 273 public function testOriginalCloneSettingConsidered() 274 { 275 $mock1 = $this->getMock('PartialMockTestClass'); 276 $mock2 = $this->getMock('PartialMockTestClass', array(), array(), '', TRUE, FALSE); 277 278 $this->assertNotEquals(get_class($mock1), get_class($mock2)); 279 } 280 281 public function testStubbedReturnValueForStaticMethod() 282 { 283 $this->getMockClass( 284 'StaticMockTestClass', 285 array('doSomething'), 286 array(), 287 'StaticMockTestClassMock' 288 ); 289 290 StaticMockTestClassMock::staticExpects($this->any()) 291 ->method('doSomething') 292 ->will($this->returnValue('something')); 293 294 $this->assertEquals( 295 'something', StaticMockTestClassMock::doSomething() 296 ); 297 } 298 299 public function testStubbedReturnValueForStaticMethod2() 300 { 301 $this->getMockClass( 302 'StaticMockTestClass', 303 array('doSomething'), 304 array(), 305 'StaticMockTestClassMock2' 306 ); 307 308 StaticMockTestClassMock2::staticExpects($this->any()) 309 ->method('doSomething') 310 ->will($this->returnValue('something')); 311 312 $this->assertEquals( 313 'something', StaticMockTestClassMock2::doSomethingElse() 314 ); 315 } 316 317 public function testGetMockForAbstractClass() 318 { 319 $mock = $this->getMock('AbstractMockTestClass'); 320 $mock->expects($this->never()) 321 ->method('doSomething'); 322 } 323 324 public function testClonedMockObjectShouldStillEqualTheOriginal() 325 { 326 $a = $this->getMock('stdClass'); 327 $b = clone $a; 328 $this->assertEquals($a, $b); 329 } 330 331 public function testMockObjectsConstructedIndepentantlyShouldBeEqual() 332 { 333 $a = $this->getMock('stdClass'); 334 $b = $this->getMock('stdClass'); 335 $this->assertEquals($a, $b); 336 } 337 338 public function testMockObjectsConstructedIndepentantlyShouldNotBeTheSame() 339 { 340 $a = $this->getMock('stdClass'); 341 $b = $this->getMock('stdClass'); 342 $this->assertNotSame($a, $b); 343 } 344 345 public function testClonedMockObjectCanBeUsedInPlaceOfOriginalOne() 346 { 347 $x = $this->getMock('stdClass'); 348 $y = clone $x; 349 350 $mock = $this->getMock('stdClass', array('foo')); 351 $mock->expects($this->once())->method('foo')->with($this->equalTo($x)); 352 $mock->foo($y); 353 } 354 355 public function testClonedMockObjectIsNotIdenticalToOriginalOne() 356 { 357 $x = $this->getMock('stdClass'); 358 $y = clone $x; 359 360 $mock = $this->getMock('stdClass', array('foo')); 361 $mock->expects($this->once())->method('foo')->with($this->logicalNot($this->identicalTo($x))); 362 $mock->foo($y); 363 } 364 365 public function testStaticMethodCallWithArgumentCloningEnabled() 366 { 367 $expectedObject = new StdClass; 368 369 $this->getMockClass( 370 'StaticMockTestClass', 371 array('doSomething'), 372 array(), 373 'StaticMockTestClassMock3', 374 FALSE, 375 TRUE, 376 TRUE, 377 TRUE 378 ); 379 380 $actualArguments = array(); 381 382 StaticMockTestClassMock3::staticExpects($this->any()) 383 ->method('doSomething') 384 ->will($this->returnCallback(function() use (&$actualArguments) { 385 $actualArguments = func_get_args(); 386 })); 387 388 StaticMockTestClassMock3::doSomething($expectedObject); 389 390 $this->assertEquals(1, count($actualArguments)); 391 $this->assertNotSame($expectedObject, $actualArguments[0]); 392 } 393 394 public function testStaticMethodCallWithArgumentCloningDisabled() 395 { 396 $expectedObject = new StdClass; 397 398 $this->getMockClass( 399 'StaticMockTestClass', 400 array('doSomething'), 401 array(), 402 'StaticMockTestClassMock4', 403 FALSE, 404 TRUE, 405 TRUE, 406 FALSE 407 ); 408 409 $actualArguments = array(); 410 411 StaticMockTestClassMock4::staticExpects($this->any()) 412 ->method('doSomething') 413 ->will($this->returnCallback(function() use (&$actualArguments) { 414 $actualArguments = func_get_args(); 415 })); 416 417 StaticMockTestClassMock4::doSomething($expectedObject); 418 419 $this->assertEquals(1, count($actualArguments)); 420 $this->assertEquals($expectedObject, $actualArguments[0]); 421 $this->assertSame($expectedObject, $actualArguments[0]); 422 } 423 424 public function testObjectMethodCallWithArgumentCloningEnabled() 425 { 426 $expectedObject = new StdClass; 427 428 $mock = $this->getMockBuilder('SomeClass') 429 ->setMethods(array('doSomethingElse')) 430 ->enableArgumentCloning() 431 ->getMock(); 432 433 $actualArguments = array(); 434 435 $mock->expects($this->any()) 436 ->method('doSomethingElse') 437 ->will($this->returnCallback(function() use (&$actualArguments) { 438 $actualArguments = func_get_args(); 439 })); 440 441 $mock->doSomethingElse($expectedObject); 442 443 $this->assertEquals(1, count($actualArguments)); 444 $this->assertEquals($expectedObject, $actualArguments[0]); 445 $this->assertNotSame($expectedObject, $actualArguments[0]); 446 } 447 448 public function testObjectMethodCallWithArgumentCloningDisabled() 449 { 450 $expectedObject = new StdClass; 451 452 $mock = $this->getMockBuilder('SomeClass') 453 ->setMethods(array('doSomethingElse')) 454 ->disableArgumentCloning() 455 ->getMock(); 456 457 $actualArguments = array(); 458 459 $mock->expects($this->any()) 460 ->method('doSomethingElse') 461 ->will($this->returnCallback(function() use (&$actualArguments) { 462 $actualArguments = func_get_args(); 463 })); 464 465 $mock->doSomethingElse($expectedObject); 466 467 $this->assertEquals(1, count($actualArguments)); 468 $this->assertSame($expectedObject, $actualArguments[0]); 469 } 470 471 public function testArgumentCloningOptionGeneratesUniqueMock() 472 { 473 $mockWithCloning = $this->getMockBuilder('SomeClass') 474 ->setMethods(array('doSomethingElse')) 475 ->enableArgumentCloning() 476 ->getMock(); 477 478 $mockWithoutCloning = $this->getMockBuilder('SomeClass') 479 ->setMethods(array('doSomethingElse')) 480 ->disableArgumentCloning() 481 ->getMock(); 482 483 $this->assertNotEquals($mockWithCloning, $mockWithoutCloning); 484 } 485 486 public function testVerificationOfMethodNameFailsWithoutParameters() 487 { 488 $mock = $this->getMock('SomeClass', array('right', 'wrong'), array(), '', TRUE, TRUE, TRUE); 489 $mock->expects($this->once()) 490 ->method('right'); 491 492 $mock->wrong(); 493 try { 494 $mock->__phpunit_verify(); 495 $this->fail('Expected exception'); 496 } catch (PHPUnit_Framework_ExpectationFailedException $e) { 497 $this->assertSame( 498 "Expectation failed for method name is equal to <string:right> when invoked 1 time(s).\n" 499 . 'Method was expected to be called 1 times, actually called 0 times.', 500 $e->getMessage() 501 ); 502 } 503 504 $this->resetMockObjects(); 505 } 506 507 public function testVerificationOfMethodNameFailsWithParameters() 508 { 509 $mock = $this->getMock('SomeClass', array('right', 'wrong'), array(), '', TRUE, TRUE, TRUE); 510 $mock->expects($this->once()) 511 ->method('right'); 512 513 $mock->wrong(); 514 try { 515 $mock->__phpunit_verify(); 516 $this->fail('Expected exception'); 517 } catch (PHPUnit_Framework_ExpectationFailedException $e) { 518 $this->assertSame( 519 "Expectation failed for method name is equal to <string:right> when invoked 1 time(s).\n" 520 . 'Method was expected to be called 1 times, actually called 0 times.', 521 $e->getMessage() 522 ); 523 } 524 525 $this->resetMockObjects(); 526 } 527 528 public function testVerificationOfNeverFailsWithEmptyParameters() 529 { 530 $mock = $this->getMock('SomeClass', array('right', 'wrong'), array(), '', TRUE, TRUE, TRUE); 531 $mock->expects($this->never()) 532 ->method('right') 533 ->with(); 534 535 try { 536 $mock->right(); 537 $this->fail('Expected exception'); 538 } catch (PHPUnit_Framework_ExpectationFailedException $e) { 539 $this->assertSame( 540 'SomeClass::right() was not expected to be called.', 541 $e->getMessage() 542 ); 543 } 544 545 $this->resetMockObjects(); 546 } 547 548 public function testVerificationOfNeverFailsWithAnyParameters() 549 { 550 $mock = $this->getMock('SomeClass', array('right', 'wrong'), array(), '', TRUE, TRUE, TRUE); 551 $mock->expects($this->never()) 552 ->method('right') 553 ->withAnyParameters(); 554 555 try { 556 $mock->right(); 557 $this->fail('Expected exception'); 558 } catch (PHPUnit_Framework_ExpectationFailedException $e) { 559 $this->assertSame( 560 'SomeClass::right() was not expected to be called.', 561 $e->getMessage() 562 ); 563 } 564 565 $this->resetMockObjects(); 566 } 567 568 public function testMockArgumentsPassedByReference() { 569 $foo = $this->getMockBuilder('MethodCallbackByReference') 570 ->setMethods(array('bar')) 571 ->disableOriginalConstructor() 572 ->disableArgumentCloning() 573 ->getMock(); 574 575 $foo->expects($this->any()) 576 ->method('bar') 577 ->will($this->returnCallback(array($foo, 'callback'))); 578 579 $a = $b = $c = 0; 580 581 $foo->bar($a, $b, $c); 582 583 $this->assertEquals(1, $b); 584 } 585 586 public function testMockArgumentsPassedByReference2() { 587 $foo = $this->getMockBuilder('MethodCallbackByReference') 588 ->disableOriginalConstructor() 589 ->disableArgumentCloning() 590 ->getMock(); 591 592 $foo->expects($this->any()) 593 ->method('bar') 594 ->will($this->returnCallback( 595 function ($a, &$b, $c) { 596 $b = 1; 597 } 598 )); 599 600 $a = $b = $c = 0; 601 602 $foo->bar($a, $b, $c); 603 604 $this->assertEquals(1, $b); 605 } 606 607 /** 608 * @requires extension soap 609 */ 610 public function testCreateMockFromWsdl() 611 { 612 $mock = $this->getMockFromWsdl(__DIR__ . '/_files/GoogleSearch.wsdl', 'WsdlMock'); 613 $this->assertStringStartsWith( 614 'Mock_WsdlMock_', 615 get_class($mock) 616 ); 617 } 618 619 /** 620 * @requires extension soap 621 */ 622 public function testCreateNamespacedMockFromWsdl() 623 { 624 $mock = $this->getMockFromWsdl(__DIR__ . '/_files/GoogleSearch.wsdl', 'My\\Space\\WsdlMock'); 625 $this->assertStringStartsWith( 626 'Mock_WsdlMock_', 627 get_class($mock) 628 ); 629 } 630 631 /** 632 * @requires extension soap 633 */ 634 public function testCreateTwoMocksOfOneWsdlFile() 635 { 636 $mock = $this->getMockFromWsdl(__DIR__ . '/_files/GoogleSearch.wsdl'); 637 $mock = $this->getMockFromWsdl(__DIR__ . '/_files/GoogleSearch.wsdl'); 638 } 639 640 private function resetMockObjects() 641 { 642 $refl = new ReflectionObject($this); 643 $refl = $refl->getParentClass(); 644 $prop = $refl->getProperty('mockObjects'); 645 $prop->setAccessible(true); 646 $prop->setValue($this, array()); 647 } 648 }