Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@14: use PHPUnit\Framework\MockObject\MockObject; Chris@14: use PHPUnit\Framework\TestCase; Chris@14: use PHPUnit\Framework\ExpectationFailedException; Chris@14: Chris@14: class MockObjectTest extends TestCase Chris@0: { Chris@0: public function testMockedMethodIsNeverCalled() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->never()) Chris@0: ->method('doSomething'); Chris@0: } Chris@0: Chris@0: public function testMockedMethodIsNeverCalledWithParameter() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->never()) Chris@14: ->method('doSomething') Chris@14: ->with('someArg'); Chris@0: } Chris@0: Chris@14: /** Chris@14: * @doesNotPerformAssertions Chris@14: */ Chris@0: public function testMockedMethodIsNotCalledWhenExpectsAnyWithParameter() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomethingElse') Chris@0: ->with('someArg'); Chris@0: } Chris@0: Chris@14: /** Chris@14: * @doesNotPerformAssertions Chris@14: */ Chris@0: public function testMockedMethodIsNotCalledWhenMethodSpecifiedDirectlyWithParameter() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->method('doSomethingElse') Chris@14: ->with('someArg'); Chris@0: } Chris@0: Chris@0: public function testMockedMethodIsCalledAtLeastOnce() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->atLeastOnce()) Chris@0: ->method('doSomething'); Chris@0: Chris@0: $mock->doSomething(); Chris@0: } Chris@0: Chris@0: public function testMockedMethodIsCalledAtLeastOnce2() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->atLeastOnce()) Chris@0: ->method('doSomething'); Chris@0: Chris@0: $mock->doSomething(); Chris@0: $mock->doSomething(); Chris@0: } Chris@0: Chris@0: public function testMockedMethodIsCalledAtLeastTwice() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->atLeast(2)) Chris@0: ->method('doSomething'); Chris@0: Chris@0: $mock->doSomething(); Chris@0: $mock->doSomething(); Chris@0: } Chris@0: Chris@0: public function testMockedMethodIsCalledAtLeastTwice2() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->atLeast(2)) Chris@0: ->method('doSomething'); Chris@0: Chris@0: $mock->doSomething(); Chris@0: $mock->doSomething(); Chris@0: $mock->doSomething(); Chris@0: } Chris@0: Chris@0: public function testMockedMethodIsCalledAtMostTwice() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->atMost(2)) Chris@0: ->method('doSomething'); Chris@0: Chris@0: $mock->doSomething(); Chris@0: $mock->doSomething(); Chris@0: } Chris@0: Chris@0: public function testMockedMethodIsCalledAtMosttTwice2() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->atMost(2)) Chris@0: ->method('doSomething'); Chris@0: Chris@0: $mock->doSomething(); Chris@0: } Chris@0: Chris@0: public function testMockedMethodIsCalledOnce() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->once()) Chris@0: ->method('doSomething'); Chris@0: Chris@0: $mock->doSomething(); Chris@0: } Chris@0: Chris@0: public function testMockedMethodIsCalledOnceWithParameter() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->once()) Chris@0: ->method('doSomethingElse') Chris@0: ->with($this->equalTo('something')); Chris@0: Chris@0: $mock->doSomethingElse('something'); Chris@0: } Chris@0: Chris@0: public function testMockedMethodIsCalledExactly() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->exactly(2)) Chris@0: ->method('doSomething'); Chris@0: Chris@0: $mock->doSomething(); Chris@0: $mock->doSomething(); Chris@0: } Chris@0: Chris@0: public function testStubbedException() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@14: ->will($this->throwException(new \Exception())); Chris@0: Chris@14: $this->expectException(\Exception::class); Chris@0: Chris@14: $mock->doSomething(); Chris@0: } Chris@0: Chris@0: public function testStubbedWillThrowException() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@14: ->willThrowException(new \Exception()); Chris@0: Chris@14: $this->expectException(\Exception::class); Chris@0: Chris@14: $mock->doSomething(); Chris@0: } Chris@0: Chris@0: public function testStubbedReturnValue() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->will($this->returnValue('something')); Chris@0: Chris@0: $this->assertEquals('something', $mock->doSomething()); Chris@0: Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->willReturn('something'); Chris@0: Chris@0: $this->assertEquals('something', $mock->doSomething()); Chris@0: } Chris@0: Chris@0: public function testStubbedReturnValueMap() Chris@0: { Chris@14: $map = [ Chris@14: ['a', 'b', 'c', 'd'], Chris@14: ['e', 'f', 'g', 'h'] Chris@14: ]; Chris@0: Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->will($this->returnValueMap($map)); Chris@0: Chris@0: $this->assertEquals('d', $mock->doSomething('a', 'b', 'c')); Chris@0: $this->assertEquals('h', $mock->doSomething('e', 'f', 'g')); Chris@0: $this->assertEquals(null, $mock->doSomething('foo', 'bar')); Chris@0: Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->willReturnMap($map); Chris@0: Chris@0: $this->assertEquals('d', $mock->doSomething('a', 'b', 'c')); Chris@0: $this->assertEquals('h', $mock->doSomething('e', 'f', 'g')); Chris@0: $this->assertEquals(null, $mock->doSomething('foo', 'bar')); Chris@0: } Chris@0: Chris@0: public function testStubbedReturnArgument() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->will($this->returnArgument(1)); Chris@0: Chris@0: $this->assertEquals('b', $mock->doSomething('a', 'b')); Chris@0: Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->willReturnArgument(1); Chris@0: Chris@0: $this->assertEquals('b', $mock->doSomething('a', 'b')); Chris@0: } Chris@0: Chris@0: public function testFunctionCallback() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->setMethods(['doSomething']) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->once()) Chris@0: ->method('doSomething') Chris@0: ->will($this->returnCallback('functionCallback')); Chris@0: Chris@0: $this->assertEquals('pass', $mock->doSomething('foo', 'bar')); Chris@0: Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->setMethods(['doSomething']) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->once()) Chris@0: ->method('doSomething') Chris@0: ->willReturnCallback('functionCallback'); Chris@0: Chris@0: $this->assertEquals('pass', $mock->doSomething('foo', 'bar')); Chris@0: } Chris@0: Chris@0: public function testStubbedReturnSelf() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->will($this->returnSelf()); Chris@0: Chris@0: $this->assertEquals($mock, $mock->doSomething()); Chris@0: Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->willReturnSelf(); Chris@0: Chris@0: $this->assertEquals($mock, $mock->doSomething()); Chris@0: } Chris@0: Chris@0: public function testStubbedReturnOnConsecutiveCalls() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->will($this->onConsecutiveCalls('a', 'b', 'c')); Chris@0: Chris@0: $this->assertEquals('a', $mock->doSomething()); Chris@0: $this->assertEquals('b', $mock->doSomething()); Chris@0: $this->assertEquals('c', $mock->doSomething()); Chris@0: Chris@14: $mock = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->any()) Chris@0: ->method('doSomething') Chris@0: ->willReturnOnConsecutiveCalls('a', 'b', 'c'); Chris@0: Chris@0: $this->assertEquals('a', $mock->doSomething()); Chris@0: $this->assertEquals('b', $mock->doSomething()); Chris@0: $this->assertEquals('c', $mock->doSomething()); Chris@0: } Chris@0: Chris@0: public function testStaticMethodCallback() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->setMethods(['doSomething']) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->once()) Chris@0: ->method('doSomething') Chris@14: ->will($this->returnCallback(['MethodCallback', 'staticCallback'])); Chris@0: Chris@0: $this->assertEquals('pass', $mock->doSomething('foo', 'bar')); Chris@0: } Chris@0: Chris@0: public function testPublicMethodCallback() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->setMethods(['doSomething']) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->once()) Chris@0: ->method('doSomething') Chris@14: ->will($this->returnCallback([new MethodCallback, 'nonStaticCallback'])); Chris@0: Chris@0: $this->assertEquals('pass', $mock->doSomething('foo', 'bar')); Chris@0: } Chris@0: Chris@0: public function testMockClassOnlyGeneratedOnce() Chris@0: { Chris@14: $mock1 = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@14: Chris@14: $mock2 = $this->getMockBuilder(AnInterface::class) Chris@14: ->getMock(); Chris@0: Chris@0: $this->assertEquals(get_class($mock1), get_class($mock2)); Chris@0: } Chris@0: Chris@0: public function testMockClassDifferentForPartialMocks() Chris@0: { Chris@14: $mock1 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->getMock(); Chris@14: Chris@14: $mock2 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->setMethods(['doSomething']) Chris@14: ->getMock(); Chris@14: Chris@14: $mock3 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->setMethods(['doSomething']) Chris@14: ->getMock(); Chris@14: Chris@14: $mock4 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->setMethods(['doAnotherThing']) Chris@14: ->getMock(); Chris@14: Chris@14: $mock5 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->setMethods(['doAnotherThing']) Chris@14: ->getMock(); Chris@0: Chris@0: $this->assertNotEquals(get_class($mock1), get_class($mock2)); Chris@0: $this->assertNotEquals(get_class($mock1), get_class($mock3)); Chris@0: $this->assertNotEquals(get_class($mock1), get_class($mock4)); Chris@0: $this->assertNotEquals(get_class($mock1), get_class($mock5)); Chris@0: $this->assertEquals(get_class($mock2), get_class($mock3)); Chris@0: $this->assertNotEquals(get_class($mock2), get_class($mock4)); Chris@0: $this->assertNotEquals(get_class($mock2), get_class($mock5)); Chris@0: $this->assertEquals(get_class($mock4), get_class($mock5)); Chris@0: } Chris@0: Chris@0: public function testMockClassStoreOverrulable() Chris@0: { Chris@14: $mock1 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->getMock(); Chris@14: Chris@14: $mock2 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->setMockClassName('MyMockClassNameForPartialMockTestClass1') Chris@14: ->getMock(); Chris@14: Chris@14: $mock3 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->getMock(); Chris@14: Chris@14: $mock4 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->setMethods(['doSomething']) Chris@14: ->setMockClassName('AnotherMockClassNameForPartialMockTestClass') Chris@14: ->getMock(); Chris@14: Chris@14: $mock5 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->setMockClassName('MyMockClassNameForPartialMockTestClass2') Chris@14: ->getMock(); Chris@0: Chris@0: $this->assertNotEquals(get_class($mock1), get_class($mock2)); Chris@0: $this->assertEquals(get_class($mock1), get_class($mock3)); Chris@0: $this->assertNotEquals(get_class($mock1), get_class($mock4)); Chris@0: $this->assertNotEquals(get_class($mock2), get_class($mock3)); Chris@0: $this->assertNotEquals(get_class($mock2), get_class($mock4)); Chris@0: $this->assertNotEquals(get_class($mock2), get_class($mock5)); Chris@0: $this->assertNotEquals(get_class($mock3), get_class($mock4)); Chris@0: $this->assertNotEquals(get_class($mock3), get_class($mock5)); Chris@0: $this->assertNotEquals(get_class($mock4), get_class($mock5)); Chris@0: } Chris@0: Chris@0: public function testGetMockWithFixedClassNameCanProduceTheSameMockTwice() Chris@0: { Chris@14: $mock = $this->getMockBuilder(stdClass::class)->setMockClassName('FixedName')->getMock(); Chris@14: $mock = $this->getMockBuilder(stdClass::class)->setMockClassName('FixedName')->getMock(); Chris@14: $this->assertInstanceOf(stdClass::class, $mock); Chris@0: } Chris@0: Chris@0: public function testOriginalConstructorSettingConsidered() Chris@0: { Chris@14: $mock1 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->getMock(); Chris@14: Chris@14: $mock2 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->disableOriginalConstructor() Chris@14: ->getMock(); Chris@0: Chris@0: $this->assertTrue($mock1->constructorCalled); Chris@0: $this->assertFalse($mock2->constructorCalled); Chris@0: } Chris@0: Chris@0: public function testOriginalCloneSettingConsidered() Chris@0: { Chris@14: $mock1 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->getMock(); Chris@14: Chris@14: $mock2 = $this->getMockBuilder(PartialMockTestClass::class) Chris@14: ->disableOriginalClone() Chris@14: ->getMock(); Chris@0: Chris@0: $this->assertNotEquals(get_class($mock1), get_class($mock2)); Chris@0: } Chris@0: Chris@0: public function testGetMockForAbstractClass() Chris@0: { Chris@14: $mock = $this->getMockBuilder(AbstractMockTestClass::class) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->never()) Chris@0: ->method('doSomething'); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @dataProvider traversableProvider Chris@0: */ Chris@0: public function testGetMockForTraversable($type) Chris@0: { Chris@14: $mock = $this->getMockBuilder($type) Chris@14: ->getMock(); Chris@14: Chris@14: $this->assertInstanceOf(Traversable::class, $mock); Chris@0: } Chris@0: Chris@0: public function testMultipleInterfacesCanBeMockedInSingleObject() Chris@0: { Chris@14: $mock = $this->getMockBuilder([AnInterface::class, AnotherInterface::class]) Chris@14: ->getMock(); Chris@14: Chris@14: $this->assertInstanceOf(AnInterface::class, $mock); Chris@14: $this->assertInstanceOf(AnotherInterface::class, $mock); Chris@0: } Chris@0: Chris@0: public function testGetMockForTrait() Chris@0: { Chris@14: $mock = $this->getMockForTrait(AbstractTrait::class); Chris@14: Chris@14: $mock->expects($this->never()) Chris@14: ->method('doSomething'); Chris@0: Chris@0: $parent = get_parent_class($mock); Chris@0: $traits = class_uses($parent, false); Chris@0: Chris@14: $this->assertContains(AbstractTrait::class, $traits); Chris@0: } Chris@0: Chris@0: public function testClonedMockObjectShouldStillEqualTheOriginal() Chris@0: { Chris@14: $a = $this->getMockBuilder(stdClass::class) Chris@14: ->getMock(); Chris@14: Chris@0: $b = clone $a; Chris@14: Chris@0: $this->assertEquals($a, $b); Chris@0: } Chris@0: Chris@0: public function testMockObjectsConstructedIndepentantlyShouldBeEqual() Chris@0: { Chris@14: $a = $this->getMockBuilder(stdClass::class) Chris@14: ->getMock(); Chris@14: Chris@14: $b = $this->getMockBuilder(stdClass::class) Chris@14: ->getMock(); Chris@14: Chris@0: $this->assertEquals($a, $b); Chris@0: } Chris@0: Chris@0: public function testMockObjectsConstructedIndepentantlyShouldNotBeTheSame() Chris@0: { Chris@14: $a = $this->getMockBuilder(stdClass::class) Chris@14: ->getMock(); Chris@14: Chris@14: $b = $this->getMockBuilder(stdClass::class) Chris@14: ->getMock(); Chris@14: Chris@0: $this->assertNotSame($a, $b); Chris@0: } Chris@0: Chris@0: public function testClonedMockObjectCanBeUsedInPlaceOfOriginalOne() Chris@0: { Chris@14: $x = $this->getMockBuilder(stdClass::class) Chris@14: ->getMock(); Chris@14: Chris@0: $y = clone $x; Chris@0: Chris@14: $mock = $this->getMockBuilder(stdClass::class) Chris@14: ->setMethods(['foo']) Chris@14: ->getMock(); Chris@14: Chris@14: $mock->expects($this->once()) Chris@14: ->method('foo') Chris@14: ->with($this->equalTo($x)); Chris@14: Chris@0: $mock->foo($y); Chris@0: } Chris@0: Chris@0: public function testClonedMockObjectIsNotIdenticalToOriginalOne() Chris@0: { Chris@14: $x = $this->getMockBuilder(stdClass::class) Chris@14: ->getMock(); Chris@14: Chris@0: $y = clone $x; Chris@0: Chris@14: $mock = $this->getMockBuilder(stdClass::class) Chris@14: ->setMethods(['foo']) Chris@14: ->getMock(); Chris@14: Chris@14: $mock->expects($this->once()) Chris@14: ->method('foo') Chris@14: ->with($this->logicalNot($this->identicalTo($x))); Chris@14: Chris@0: $mock->foo($y); Chris@0: } Chris@0: Chris@0: public function testObjectMethodCallWithArgumentCloningEnabled() Chris@0: { Chris@14: $expectedObject = new stdClass; Chris@0: Chris@0: $mock = $this->getMockBuilder('SomeClass') Chris@14: ->setMethods(['doSomethingElse']) Chris@0: ->enableArgumentCloning() Chris@0: ->getMock(); Chris@0: Chris@14: $actualArguments = []; Chris@0: Chris@0: $mock->expects($this->any()) Chris@14: ->method('doSomethingElse') Chris@14: ->will( Chris@14: $this->returnCallback( Chris@14: function () use (&$actualArguments) { Chris@14: $actualArguments = func_get_args(); Chris@14: } Chris@14: ) Chris@14: ); Chris@0: Chris@0: $mock->doSomethingElse($expectedObject); Chris@0: Chris@0: $this->assertEquals(1, count($actualArguments)); Chris@0: $this->assertEquals($expectedObject, $actualArguments[0]); Chris@0: $this->assertNotSame($expectedObject, $actualArguments[0]); Chris@0: } Chris@0: Chris@0: public function testObjectMethodCallWithArgumentCloningDisabled() Chris@0: { Chris@14: $expectedObject = new stdClass; Chris@0: Chris@0: $mock = $this->getMockBuilder('SomeClass') Chris@14: ->setMethods(['doSomethingElse']) Chris@0: ->disableArgumentCloning() Chris@0: ->getMock(); Chris@0: Chris@14: $actualArguments = []; Chris@0: Chris@0: $mock->expects($this->any()) Chris@14: ->method('doSomethingElse') Chris@14: ->will( Chris@14: $this->returnCallback( Chris@14: function () use (&$actualArguments) { Chris@14: $actualArguments = func_get_args(); Chris@14: } Chris@14: ) Chris@14: ); Chris@0: Chris@0: $mock->doSomethingElse($expectedObject); Chris@0: Chris@0: $this->assertEquals(1, count($actualArguments)); Chris@0: $this->assertSame($expectedObject, $actualArguments[0]); Chris@0: } Chris@0: Chris@0: public function testArgumentCloningOptionGeneratesUniqueMock() Chris@0: { Chris@0: $mockWithCloning = $this->getMockBuilder('SomeClass') Chris@14: ->setMethods(['doSomethingElse']) Chris@0: ->enableArgumentCloning() Chris@0: ->getMock(); Chris@0: Chris@0: $mockWithoutCloning = $this->getMockBuilder('SomeClass') Chris@14: ->setMethods(['doSomethingElse']) Chris@0: ->disableArgumentCloning() Chris@0: ->getMock(); Chris@0: Chris@0: $this->assertNotEquals($mockWithCloning, $mockWithoutCloning); Chris@0: } Chris@0: Chris@0: public function testVerificationOfMethodNameFailsWithoutParameters() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->setMethods(['right', 'wrong']) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->once()) Chris@0: ->method('right'); Chris@0: Chris@0: $mock->wrong(); Chris@14: Chris@0: try { Chris@0: $mock->__phpunit_verify(); Chris@0: $this->fail('Expected exception'); Chris@14: } catch (ExpectationFailedException $e) { Chris@0: $this->assertSame( Chris@14: 'Expectation failed for method name is equal to "right" when invoked 1 time(s).' . PHP_EOL . Chris@14: 'Method was expected to be called 1 times, actually called 0 times.' . PHP_EOL, Chris@0: $e->getMessage() Chris@0: ); Chris@0: } Chris@0: Chris@0: $this->resetMockObjects(); Chris@0: } Chris@0: Chris@0: public function testVerificationOfMethodNameFailsWithParameters() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->setMethods(['right', 'wrong']) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->once()) Chris@0: ->method('right'); Chris@0: Chris@0: $mock->wrong(); Chris@14: Chris@0: try { Chris@0: $mock->__phpunit_verify(); Chris@0: $this->fail('Expected exception'); Chris@14: } catch (ExpectationFailedException $e) { Chris@0: $this->assertSame( Chris@14: 'Expectation failed for method name is equal to "right" when invoked 1 time(s).' . PHP_EOL . Chris@14: 'Method was expected to be called 1 times, actually called 0 times.' . PHP_EOL, Chris@0: $e->getMessage() Chris@0: ); Chris@0: } Chris@0: Chris@0: $this->resetMockObjects(); Chris@0: } Chris@0: Chris@0: public function testVerificationOfMethodNameFailsWithWrongParameters() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->setMethods(['right', 'wrong']) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->once()) Chris@0: ->method('right') Chris@14: ->with(['first', 'second']); Chris@0: Chris@0: try { Chris@14: $mock->right(['second']); Chris@14: } catch (ExpectationFailedException $e) { Chris@0: $this->assertSame( Chris@14: 'Expectation failed for method name is equal to "right" when invoked 1 time(s)' . PHP_EOL . Chris@14: 'Parameter 0 for invocation SomeClass::right(Array (...)) does not match expected value.' . PHP_EOL . Chris@14: 'Failed asserting that two arrays are equal.', Chris@0: $e->getMessage() Chris@0: ); Chris@0: } Chris@0: Chris@0: try { Chris@0: $mock->__phpunit_verify(); Chris@14: Chris@14: // CHECKOUT THIS MORE CAREFULLY Chris@14: // $this->fail('Expected exception'); Chris@14: Chris@14: } catch (ExpectationFailedException $e) { Chris@0: $this->assertSame( Chris@14: 'Expectation failed for method name is equal to "right" when invoked 1 time(s).' . PHP_EOL . Chris@14: 'Parameter 0 for invocation SomeClass::right(Array (...)) does not match expected value.' . PHP_EOL . Chris@14: 'Failed asserting that two arrays are equal.' . PHP_EOL . Chris@14: '--- Expected' . PHP_EOL . Chris@14: '+++ Actual' . PHP_EOL . Chris@14: '@@ @@' . PHP_EOL . Chris@14: ' Array (' . PHP_EOL . Chris@14: '- 0 => \'first\'' . PHP_EOL . Chris@14: '- 1 => \'second\'' . PHP_EOL . Chris@14: '+ 0 => \'second\'' . PHP_EOL, Chris@0: $e->getMessage() Chris@0: ); Chris@0: } Chris@0: Chris@0: $this->resetMockObjects(); Chris@0: } Chris@0: Chris@0: public function testVerificationOfNeverFailsWithEmptyParameters() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->setMethods(['right', 'wrong']) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->never()) Chris@0: ->method('right') Chris@0: ->with(); Chris@0: Chris@0: try { Chris@0: $mock->right(); Chris@0: $this->fail('Expected exception'); Chris@14: } catch (ExpectationFailedException $e) { Chris@0: $this->assertSame( Chris@0: 'SomeClass::right() was not expected to be called.', Chris@0: $e->getMessage() Chris@0: ); Chris@0: } Chris@0: Chris@0: $this->resetMockObjects(); Chris@0: } Chris@0: Chris@0: public function testVerificationOfNeverFailsWithAnyParameters() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->setMethods(['right', 'wrong']) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->never()) Chris@0: ->method('right') Chris@0: ->withAnyParameters(); Chris@0: Chris@0: try { Chris@0: $mock->right(); Chris@0: $this->fail('Expected exception'); Chris@14: } catch (ExpectationFailedException $e) { Chris@0: $this->assertSame( Chris@0: 'SomeClass::right() was not expected to be called.', Chris@0: $e->getMessage() Chris@0: ); Chris@0: } Chris@0: Chris@0: $this->resetMockObjects(); Chris@0: } Chris@0: Chris@0: public function testWithAnythingInsteadOfWithAnyParameters() Chris@0: { Chris@14: $mock = $this->getMockBuilder(SomeClass::class) Chris@14: ->setMethods(['right', 'wrong']) Chris@14: ->getMock(); Chris@14: Chris@0: $mock->expects($this->once()) Chris@0: ->method('right') Chris@0: ->with($this->anything()); Chris@0: Chris@0: try { Chris@0: $mock->right(); Chris@0: $this->fail('Expected exception'); Chris@14: } catch (ExpectationFailedException $e) { Chris@0: $this->assertSame( Chris@14: 'Expectation failed for method name is equal to "right" when invoked 1 time(s)' . PHP_EOL . Chris@14: 'Parameter count for invocation SomeClass::right() is too low.' . PHP_EOL . Chris@14: 'To allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead.', Chris@0: $e->getMessage() Chris@0: ); Chris@0: } Chris@0: Chris@0: $this->resetMockObjects(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * See https://github.com/sebastianbergmann/phpunit-mock-objects/issues/81 Chris@0: */ Chris@0: public function testMockArgumentsPassedByReference() Chris@0: { Chris@0: $foo = $this->getMockBuilder('MethodCallbackByReference') Chris@14: ->setMethods(['bar']) Chris@0: ->disableOriginalConstructor() Chris@0: ->disableArgumentCloning() Chris@0: ->getMock(); Chris@0: Chris@0: $foo->expects($this->any()) Chris@0: ->method('bar') Chris@14: ->will($this->returnCallback([$foo, 'callback'])); Chris@0: Chris@0: $a = $b = $c = 0; Chris@0: Chris@0: $foo->bar($a, $b, $c); Chris@0: Chris@0: $this->assertEquals(1, $b); Chris@0: } Chris@0: Chris@0: /** Chris@0: * See https://github.com/sebastianbergmann/phpunit-mock-objects/issues/81 Chris@0: */ Chris@0: public function testMockArgumentsPassedByReference2() Chris@0: { Chris@0: $foo = $this->getMockBuilder('MethodCallbackByReference') Chris@0: ->disableOriginalConstructor() Chris@0: ->disableArgumentCloning() Chris@0: ->getMock(); Chris@0: Chris@0: $foo->expects($this->any()) Chris@0: ->method('bar') Chris@0: ->will($this->returnCallback( Chris@0: function (&$a, &$b, $c) { Chris@0: $b = 1; Chris@0: } Chris@0: )); Chris@0: Chris@0: $a = $b = $c = 0; Chris@0: Chris@0: $foo->bar($a, $b, $c); Chris@0: Chris@0: $this->assertEquals(1, $b); Chris@0: } Chris@0: Chris@0: /** Chris@14: * @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/116 Chris@0: */ Chris@0: public function testMockArgumentsPassedByReference3() Chris@0: { Chris@0: $foo = $this->getMockBuilder('MethodCallbackByReference') Chris@14: ->setMethods(['bar']) Chris@0: ->disableOriginalConstructor() Chris@0: ->disableArgumentCloning() Chris@0: ->getMock(); Chris@0: Chris@14: $a = new stdClass; Chris@0: $b = $c = 0; Chris@0: Chris@0: $foo->expects($this->any()) Chris@0: ->method('bar') Chris@0: ->with($a, $b, $c) Chris@14: ->will($this->returnCallback([$foo, 'callback'])); Chris@0: Chris@14: $this->assertNull($foo->bar($a, $b, $c)); Chris@0: } Chris@0: Chris@0: /** Chris@14: * @see https://github.com/sebastianbergmann/phpunit/issues/796 Chris@0: */ Chris@0: public function testMockArgumentsPassedByReference4() Chris@0: { Chris@0: $foo = $this->getMockBuilder('MethodCallbackByReference') Chris@14: ->setMethods(['bar']) Chris@0: ->disableOriginalConstructor() Chris@0: ->disableArgumentCloning() Chris@0: ->getMock(); Chris@0: Chris@14: $a = new stdClass; Chris@0: $b = $c = 0; Chris@0: Chris@0: $foo->expects($this->any()) Chris@0: ->method('bar') Chris@14: ->with($this->isInstanceOf(stdClass::class), $b, $c) Chris@14: ->will($this->returnCallback([$foo, 'callback'])); Chris@0: Chris@14: $this->assertNull($foo->bar($a, $b, $c)); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @requires extension soap Chris@0: */ Chris@0: public function testCreateMockFromWsdl() Chris@0: { Chris@0: $mock = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl', 'WsdlMock'); Chris@14: Chris@0: $this->assertStringStartsWith( Chris@0: 'Mock_WsdlMock_', Chris@0: get_class($mock) Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @requires extension soap Chris@0: */ Chris@0: public function testCreateNamespacedMockFromWsdl() Chris@0: { Chris@0: $mock = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl', 'My\\Space\\WsdlMock'); Chris@14: Chris@0: $this->assertStringStartsWith( Chris@0: 'Mock_WsdlMock_', Chris@0: get_class($mock) Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @requires extension soap Chris@0: */ Chris@0: public function testCreateTwoMocksOfOneWsdlFile() Chris@0: { Chris@14: $a = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl'); Chris@14: $b = $this->getMockFromWsdl(__DIR__ . '/_fixture/GoogleSearch.wsdl'); Chris@14: Chris@14: $this->assertStringStartsWith('Mock_GoogleSearch_', get_class($a)); Chris@14: $this->assertEquals(get_class($a), get_class($b)); Chris@0: } Chris@0: Chris@0: /** Chris@17: * @requires extension soap Chris@17: */ Chris@17: public function testCreateMockOfWsdlFileWithSpecialChars() Chris@17: { Chris@17: $mock = $this->getMockFromWsdl(__DIR__ . '/_fixture/Go ogle-Sea.rch.wsdl'); Chris@17: Chris@17: $this->assertStringStartsWith('Mock_GoogleSearch_', get_class($mock)); Chris@17: } Chris@17: Chris@17: /** Chris@0: * @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/156 Chris@0: * @ticket 156 Chris@0: */ Chris@0: public function testInterfaceWithStaticMethodCanBeStubbed() Chris@0: { Chris@0: $this->assertInstanceOf( Chris@14: InterfaceWithStaticMethod::class, Chris@14: $this->getMockBuilder(InterfaceWithStaticMethod::class)->getMock() Chris@0: ); Chris@0: } Chris@0: Chris@0: public function testInvokingStubbedStaticMethodRaisesException() Chris@0: { Chris@14: $mock = $this->getMockBuilder(ClassWithStaticMethod::class)->getMock(); Chris@14: Chris@14: $this->expectException(\PHPUnit\Framework\MockObject\BadMethodCallException::class); Chris@14: Chris@0: $mock->staticMethod(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/171 Chris@0: * @ticket 171 Chris@0: */ Chris@0: public function testStubForClassThatImplementsSerializableCanBeCreatedWithoutInvokingTheConstructor() Chris@0: { Chris@0: $this->assertInstanceOf( Chris@14: ClassThatImplementsSerializable::class, Chris@14: $this->getMockBuilder(ClassThatImplementsSerializable::class) Chris@0: ->disableOriginalConstructor() Chris@0: ->getMock() Chris@0: ); Chris@0: } Chris@0: Chris@14: public function testGetMockForClassWithSelfTypeHint() Chris@14: { Chris@14: $this->assertInstanceOf( Chris@14: ClassWithSelfTypeHint::class, Chris@14: $this->getMockBuilder(ClassWithSelfTypeHint::class)->getMock() Chris@14: ); Chris@14: } Chris@14: Chris@0: private function resetMockObjects() Chris@0: { Chris@0: $refl = new ReflectionObject($this); Chris@0: $refl = $refl->getParentClass(); Chris@0: $prop = $refl->getProperty('mockObjects'); Chris@0: $prop->setAccessible(true); Chris@14: $prop->setValue($this, []); Chris@14: } Chris@14: Chris@14: public function testStringableClassDoesNotThrow() Chris@14: { Chris@14: $mock = $this->getMockBuilder(StringableClass::class)->getMock(); Chris@14: Chris@14: $this->assertInternalType('string', (string) $mock); Chris@14: } Chris@14: Chris@14: public function testStringableClassCanBeMocked() Chris@14: { Chris@14: $mock = $this->getMockBuilder(StringableClass::class)->getMock(); Chris@14: Chris@14: $mock->method('__toString')->willReturn('foo'); Chris@14: Chris@14: $this->assertSame('foo', (string) $mock); Chris@14: } Chris@14: Chris@14: public function traversableProvider() Chris@14: { Chris@14: return [ Chris@14: ['Traversable'], Chris@14: ['\Traversable'], Chris@14: ['TraversableMockTestInterface'], Chris@14: [['Traversable']], Chris@14: [['Iterator','Traversable']], Chris@14: [['\Iterator','\Traversable']] Chris@14: ]; Chris@14: } Chris@14: Chris@14: public function testParameterCallbackConstraintOnlyEvaluatedOnce() Chris@14: { Chris@14: $mock = $this->getMockBuilder(Foo::class)->setMethods(['bar'])->getMock(); Chris@14: $expectedNumberOfCalls = 1; Chris@14: $callCount = 0; Chris@14: Chris@14: $mock->expects($this->exactly($expectedNumberOfCalls))->method('bar') Chris@14: ->with($this->callback(function ($argument) use (&$callCount) { Chris@14: return $argument === 'call_' . $callCount++; Chris@14: })); Chris@14: Chris@14: for ($i = 0; $i < $expectedNumberOfCalls; $i++) { Chris@14: $mock->bar('call_' . $i); Chris@14: } Chris@14: } Chris@14: Chris@14: public function testReturnTypesAreMockedCorrectly() Chris@14: { Chris@14: /** @var ClassWithAllPossibleReturnTypes|MockObject $stub */ Chris@14: $stub = $this->createMock(ClassWithAllPossibleReturnTypes::class); Chris@14: Chris@14: $this->assertNull($stub->methodWithNoReturnTypeDeclaration()); Chris@14: $this->assertSame('', $stub->methodWithStringReturnTypeDeclaration()); Chris@14: $this->assertSame(0.0, $stub->methodWithFloatReturnTypeDeclaration()); Chris@14: $this->assertSame(0, $stub->methodWithIntReturnTypeDeclaration()); Chris@14: $this->assertFalse($stub->methodWithBoolReturnTypeDeclaration()); Chris@14: $this->assertSame([], $stub->methodWithArrayReturnTypeDeclaration()); Chris@14: $this->assertInstanceOf(MockObject::class, $stub->methodWithClassReturnTypeDeclaration()); Chris@14: } Chris@14: Chris@14: /** Chris@14: * @requires PHP 7.1 Chris@14: */ Chris@14: public function testVoidReturnTypeIsMockedCorrectly() Chris@14: { Chris@14: /** @var ClassWithAllPossibleReturnTypes|MockObject $stub */ Chris@14: $stub = $this->createMock(ClassWithAllPossibleReturnTypes::class); Chris@14: Chris@14: $this->assertNull($stub->methodWithVoidReturnTypeDeclaration()); Chris@14: } Chris@14: Chris@14: /** Chris@14: * @requires PHP 7.2 Chris@14: */ Chris@14: public function testObjectReturnTypeIsMockedCorrectly() Chris@14: { Chris@14: /** @var ClassWithAllPossibleReturnTypes|MockObject $stub */ Chris@14: $stub = $this->createMock(ClassWithAllPossibleReturnTypes::class); Chris@14: Chris@14: $this->assertInstanceOf(stdClass::class, $stub->methodWithObjectReturnTypeDeclaration()); Chris@0: } Chris@0: }