From 947818bd76b070b7701da865fdbc1e310680a0ce Mon Sep 17 00:00:00 2001 From: Aaron Piotrowski Date: Wed, 22 Jul 2015 21:16:27 -0500 Subject: [PATCH] Mock return types on spies --- library/Mockery/Expectation.php | 26 +----------- library/Mockery/Mock.php | 42 +++++++++++++++++++ .../MockingParameterAndReturnTypesTest.php | 18 +++++++- 3 files changed, 60 insertions(+), 26 deletions(-) diff --git a/library/Mockery/Expectation.php b/library/Mockery/Expectation.php index 54dd9ea75..48f11cb6c 100644 --- a/library/Mockery/Expectation.php +++ b/library/Mockery/Expectation.php @@ -217,31 +217,7 @@ protected function _getReturnValue(array $args) return current($this->_returnQueue); } - $rm = $this->_mock->mockery_getMethod($this->_name); - if ($rm && version_compare(PHP_VERSION, '7.0.0-dev') >= 0 && $rm->hasReturnType()) { - $type = (string) $rm->getReturnType(); - switch ($type) { - case '': return; - case 'string': return ''; - case 'int': return 0; - case 'float': return 0.0; - case 'bool': return false; - case 'array': return []; - - case 'callable': - case 'Closure': - return function () {}; - - case 'Traversable': - case 'Generator': - // Remove eval() when minimum version >=5.5 - $generator = eval('return function () { yield; };'); - return $generator(); - - default: - return \Mockery::mock($type); - } - } + return $this->_mock->mockery_returnValueForMethod($this->_name); } /** diff --git a/library/Mockery/Mock.php b/library/Mockery/Mock.php index eb8cba157..037291c95 100644 --- a/library/Mockery/Mock.php +++ b/library/Mockery/Mock.php @@ -617,6 +617,46 @@ public function mockery_getMethod($name) return null; } + /** + * @param string $name Method name. + * + * @return mixed Generated return value based on the declared return value of the named method. + */ + public function mockery_returnValueForMethod($name) + { + if (version_compare(PHP_VERSION, '7.0.0-dev') < 0) { + return; + } + + $rm = $this->mockery_getMethod($name); + if (!$rm || !$rm->hasReturnType()) { + return; + } + + $type = (string) $rm->getReturnType(); + switch ($type) { + case '': return; + case 'string': return ''; + case 'int': return 0; + case 'float': return 0.0; + case 'bool': return false; + case 'array': return []; + + case 'callable': + case 'Closure': + return function () {}; + + case 'Traversable': + case 'Generator': + // Remove eval() when minimum version >=5.5 + $generator = eval('return function () { yield; };'); + return $generator(); + + default: + return \Mockery::mock($type); + } + } + public function shouldHaveReceived($method, $args = null) { $expectation = new \Mockery\VerificationExpectation($this, $method); @@ -707,6 +747,8 @@ protected function _mockery_handleMethodCall($method, array $args) if (\Mockery::getConfiguration()->mockingNonExistentMethodsAllowed() || (method_exists($this->_mockery_partial, $method) || is_callable("parent::$method"))) { if ($this->_mockery_defaultReturnValue instanceof \Mockery\Undefined) { return call_user_func_array(array($this->_mockery_defaultReturnValue, $method), $args); + } elseif (null === $this->_mockery_defaultReturnValue) { + return $this->mockery_returnValueForMethod($method); } else { return $this->_mockery_defaultReturnValue; } diff --git a/tests/Mockery/MockingParameterAndReturnTypesTest.php b/tests/Mockery/MockingParameterAndReturnTypesTest.php index 49c50b279..aac1b4f67 100644 --- a/tests/Mockery/MockingParameterAndReturnTypesTest.php +++ b/tests/Mockery/MockingParameterAndReturnTypesTest.php @@ -50,7 +50,7 @@ public function testMockingIntegerReturnType() $mock = $this->container->mock("test\Mockery\TestWithParameterAndReturnType"); $mock->shouldReceive("returnInteger"); - $this->assertEquals(0, $mock->returnInteger()); + $this->assertSame(0, $mock->returnInteger()); } public function testMockingFloatReturnType() @@ -108,6 +108,22 @@ public function testMockingParameterTypes() $mock->shouldReceive("withScalarParameters"); $mock->withScalarParameters(1, 1.0, true, 'string'); } + + public function testIgnoringMissingReturnsType() + { + $mock = $this->container->mock("test\Mockery\TestWithParameterAndReturnType"); + + $mock->shouldIgnoreMissing(); + + $this->assertSame('', $mock->returnString()); + $this->assertSame(0, $mock->returnInteger()); + $this->assertSame(0.0, $mock->returnFloat()); + $this->assertSame(false, $mock->returnBoolean()); + $this->assertSame([], $mock->returnArray()); + $this->assertTrue(is_callable($mock->returnCallable())); + $this->assertInstanceOf("\Generator", $mock->returnGenerator()); + $this->assertInstanceOf("test\Mockery\TestWithParameterAndReturnType", $mock->withClassReturnType()); + } }