Permalink
Browse files

- Initial work on support for mocking static methods.

  • Loading branch information...
1 parent 3eeba92 commit f174498e1d2e317c62dece64e9b48e11a79db3e8 @sebastianbergmann committed Jun 2, 2007
View
79 PHPUnit/Framework/MockObject/Invocation.php
@@ -45,18 +45,12 @@
* @since File available since Release 3.0.0
*/
-require_once 'PHPUnit/Framework.php';
require_once 'PHPUnit/Util/Filter.php';
PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
/**
- * Encapsulates information on a method invocation which can be passed to matchers.
- *
- * The invocation consists of the object it occured from, the class name, the
- * method name and all the parameters. The mock object must instantiate this
- * class with the values from the mocked method and pass it to an object of
- * PHPUnit_Framework_MockObject_Invokable.
+ * Interface for invocations.
*
* @category Testing
* @package PHPUnit
@@ -66,73 +60,12 @@
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version Release: @package_version@
* @link http://www.phpunit.de/
- * @since Class available since Release 3.0.0
+ * @since Interface available since Release 3.1.0
*/
-class PHPUnit_Framework_MockObject_Invocation implements PHPUnit_Framework_SelfDescribing
+interface PHPUnit_Framework_MockObject_Invocation
{
- public $object;
-
- public $className;
-
- public $methodName;
-
- public $parameters;
-
- public function __construct($object, $className, $methodName, $parameters)
- {
- $this->object = $object;
- $this->className = $className;
- $this->methodName = $methodName;
- $this->parameters = $parameters;
-
- foreach ($this->parameters as $key => $value) {
- if (is_object($value)) {
- $this->parameters[$key] = $this->cloneObject($value);
- }
- }
- }
-
- public function toString()
- {
- return sprintf(
- "%s::%s(%s)",
-
- $this->className,
- $this->methodName,
- join(
- ', ',
- array_map(
- create_function(
- '$a',
- 'return PHPUnit_Util_Type::shortenedExport($a);'
- ),
- $this->parameters
- )
- )
- );
- }
-
- protected function cloneObject($original)
- {
- $object = new ReflectionObject($original);
-
- if ($object->hasMethod('__clone')) {
- $method = $object->getMethod('__clone');
-
- if (!$method->isPublic()) {
- return $original;
- }
-
- try {
- return clone $original;
- }
-
- catch (Exception $e) {
- return $original;
- }
- }
-
- return clone $original;
- }
}
+
+require_once 'PHPUnit/Framework/MockObject/StaticInvocation.php';
+require_once 'PHPUnit/Framework/MockObject/ObjectInvocation.php';
?>
View
34 PHPUnit/Framework/MockObject/Mock.php
@@ -160,6 +160,7 @@ protected function generateClass()
);
}
+ //print $this->generateClassDefinition($class);
eval($this->generateClassDefinition($class));
}
@@ -208,7 +209,8 @@ protected function generateClassDefinition(ReflectionClass $class)
}
}
- $code .= "}\n";
+ $code .= "}\n\n" .
+ $this->mockClassName . '::$staticInvocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker;';
return $code;
}
@@ -258,20 +260,33 @@ protected function generateMethodDefinitionFromExisting(ReflectionMethod $method
protected function generateMethodDefinition($className, $methodName, $modifier, $reference = '', $parameters = '')
{
+ if (strpos($modifier, 'static') === FALSE) {
+ $invocationClass = 'PHPUnit_Framework_MockObject_ObjectInvocation';
+ $invocationMocker = '$this->invocationMocker';
+ $objectReference = ', $this';
+ } else {
+ $invocationClass = 'PHPUnit_Framework_MockObject_StaticInvocation';
+ $invocationMocker = 'self::$staticInvocationMocker';
+ $objectReference = '';
+ }
+
return sprintf(
"\n %s function %s%s(%s) {\n" .
" \$args = func_get_args();\n" .
- " return \$this->invocationMocker->invoke(\n" .
- " new PHPUnit_Framework_MockObject_Invocation(\$this, \"%s\", \"%s\", \$args)\n" .
+ " return %s->invoke(\n" .
+ " new %s(\"%s\", \"%s\", \$args%s)\n" .
" );\n" .
" }\n",
$modifier,
$reference,
$methodName,
$parameters,
+ $invocationMocker,
+ $invocationClass,
$className,
- $methodName
+ $methodName,
+ $objectReference
);
}
@@ -290,7 +305,8 @@ protected function generateMockApi(ReflectionClass $class)
}
return sprintf(
- " private \$invocationMocker;\n\n" .
+ " private \$invocationMocker;\n" .
+ " public static \$staticInvocationMocker;\n\n" .
"%s" .
"%s" .
" public function getInvocationMocker() {\n" .
@@ -299,7 +315,11 @@ protected function generateMockApi(ReflectionClass $class)
" public function expects(PHPUnit_Framework_MockObject_Matcher_Invocation \$matcher) {\n" .
" return \$this->invocationMocker->expects(\$matcher);\n" .
" }\n\n" .
+ " public function staticExpects(PHPUnit_Framework_MockObject_Matcher_Invocation \$matcher) {\n" .
+ " return self::\$staticInvocationMocker->expects(\$matcher);\n" .
+ " }\n\n" .
" public function verify() {\n" .
+ " self::\$staticInvocationMocker->verify();\n" .
" \$this->invocationMocker->verify();\n" .
" }\n",
@@ -311,7 +331,7 @@ protected function generateMockApi(ReflectionClass $class)
protected function generateConstructorCode()
{
return " public function __construct() {\n" .
- " \$this->invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker(\$this);\n" .
+ " \$this->invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker;\n" .
" }\n\n";
}
@@ -322,7 +342,7 @@ protected function generateConstructorCodeWithParentCall(ReflectionClass $class)
if ($constructor) {
return sprintf(
" public function __construct(%s) {\n" .
- " \$this->invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker(\$this);\n" .
+ " \$this->invocationMocker = new PHPUnit_Framework_MockObject_InvocationMocker;\n" .
" parent::%s(%s);\n" .
" }\n\n",
View
82 PHPUnit/Framework/MockObject/ObjectInvocation.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * PHPUnit
+ *
+ * Copyright (c) 2002-2007, Sebastian Bergmann <sb@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package PHPUnit
+ * @author Jan Borsodi <jb@ez.no>
+ * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @copyright 2002-2007 Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @link http://www.phpunit.de/
+ * @since File available since Release 3.0.0
+ */
+
+require_once 'PHPUnit/Framework.php';
+require_once 'PHPUnit/Util/Filter.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+
+/**
+ * Encapsulates information on a method invocation which can be passed to matchers.
+ *
+ * The invocation consists of the object it occured from, the class name, the
+ * method name and all the parameters. The mock object must instantiate this
+ * class with the values from the mocked method and pass it to an object of
+ * PHPUnit_Framework_MockObject_Invokable.
+ *
+ * @category Testing
+ * @package PHPUnit
+ * @author Jan Borsodi <jb@ez.no>
+ * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @copyright 2002-2007 Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @link http://www.phpunit.de/
+ * @since Class available since Release 3.0.0
+ */
+class PHPUnit_Framework_MockObject_ObjectInvocation extends PHPUnit_Framework_MockObject_StaticInvocation
+{
+ public $object;
+
+ public function __construct($className, $methodName, $parameters, $object)
+ {
+ parent::__construct($className, $methodName, $parameters);
+
+ $this->object = $object;
+ }
+}
+?>
View
133 PHPUnit/Framework/MockObject/StaticInvocation.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * PHPUnit
+ *
+ * Copyright (c) 2002-2007, Sebastian Bergmann <sb@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @category Testing
+ * @package PHPUnit
+ * @author Jan Borsodi <jb@ez.no>
+ * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @copyright 2002-2007 Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version SVN: $Id$
+ * @link http://www.phpunit.de/
+ * @since File available since Release 3.1.0
+ */
+
+require_once 'PHPUnit/Framework.php';
+require_once 'PHPUnit/Util/Filter.php';
+
+PHPUnit_Util_Filter::addFileToFilter(__FILE__, 'PHPUNIT');
+
+/**
+ * Encapsulates information on a method invocation which can be passed to matchers.
+ *
+ * The invocation consists of the object it occured from, the class name, the
+ * method name and all the parameters. The mock object must instantiate this
+ * class with the values from the mocked method and pass it to an object of
+ * PHPUnit_Framework_MockObject_Invokable.
+ *
+ * @category Testing
+ * @package PHPUnit
+ * @author Jan Borsodi <jb@ez.no>
+ * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @copyright 2002-2007 Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version Release: @package_version@
+ * @link http://www.phpunit.de/
+ * @since Class available since Release 3.1.0
+ */
+class PHPUnit_Framework_MockObject_StaticInvocation implements PHPUnit_Framework_MockObject_Invocation, PHPUnit_Framework_SelfDescribing
+{
+ public $className;
+ public $methodName;
+ public $parameters;
+
+ public function __construct($className, $methodName, $parameters)
+ {
+ $this->className = $className;
+ $this->methodName = $methodName;
+ $this->parameters = $parameters;
+
+ foreach ($this->parameters as $key => $value) {
+ if (is_object($value)) {
+ $this->parameters[$key] = $this->cloneObject($value);
+ }
+ }
+ }
+
+ public function toString()
+ {
+ return sprintf(
+ "%s::%s(%s)",
+
+ $this->className,
+ $this->methodName,
+ join(
+ ', ',
+ array_map(
+ create_function(
+ '$a',
+ 'return PHPUnit_Util_Type::shortenedExport($a);'
+ ),
+ $this->parameters
+ )
+ )
+ );
+ }
+
+ protected function cloneObject($original)
+ {
+ $object = new ReflectionObject($original);
+
+ if ($object->hasMethod('__clone')) {
+ $method = $object->getMethod('__clone');
+
+ if (!$method->isPublic()) {
+ return $original;
+ }
+
+ try {
+ return clone $original;
+ }
+
+ catch (Exception $e) {
+ return $original;
+ }
+ }
+
+ return clone $original;
+ }
+}
+?>

0 comments on commit f174498

Please sign in to comment.