Page 1 of 1

[Patch] PHP 5.3 + namespaces + Mock objects

Posted: Mon Feb 18, 2008 11:57 pm
by Chris Corbyn
Just thought I'd share this in the interim before it gets included in subversion of simpletest.

Code: Select all

--- tests/lib/simpletest-svn/mock_objects.php   (revision 1659)
+++ tests/lib/simpletest-svn/mock_objects.php   (working copy)
@@ -1189,6 +1189,7 @@
     var $_mock_class;
     var $_mock_base;
     var $_reflection;
+    var $_namespace;
 
     /**
      *    Builds initial reflection object.
@@ -1197,6 +1198,10 @@
      *                                but no behaviour.
      */
     function MockGenerator($class, $mock_class) {
+        if (preg_match('/^(.*?)::([^:]+)$/D', $mock_class, $matches)) {
+          $mock_class = $matches[2];
+          $this->_namespace = $matches[1];
+        }
         $this->_class = $class;
         $this->_mock_class = $mock_class;
         if (! $this->_mock_class) {
@@ -1293,8 +1298,16 @@
         if (count($interfaces) > 0) {
             $implements = 'implements ' . implode(', ', $interfaces);
         }
-        $code = "class " . $this->_mock_class . " extends " . $this->_mock_base . " $implements {\n";
-        $code .= "    function " . $this->_mock_class . "() {\n";
+        $code = "";
+        if (isset($this->_namespace)) {
+          $code .= "namespace " . $this->_namespace . ";\n";
+          $code .= "use ::" . $this->_mock_base . ";\n";
+          $constructor = "__construct";
+        } else {
+          $constructor = $this->_mock_class;
+        }
+        $code .= "class " . $this->_mock_class . " extends " . $this->_mock_base . " $implements {\n";
+        $code .= "    function " . $constructor . "() {\n";
         $code .= "        \$this->" . $this->_mock_base . "();\n";
         $code .= "    }\n";
         if (in_array('__construct', $this->_reflection->getMethods())) {
@@ -1315,11 +1328,19 @@
      *    @access private
      */
     function _createSubclassCode($methods) {
-        $code  = "class " . $this->_mock_class . " extends " . $this->_class . " {\n";
+        $code = "";
+        if (isset($this->_namespace)) {
+          $code .= "namespace " . $this->_namespace . ";\n";
+          $code .= "use ::" . $this->_mock_base . ";\n";
+          $constructor = "__construct";
+        } else {
+          $constructor = $this->_mock_class;
+        }
+        $code .= "class " . $this->_mock_class . " extends " . $this->_class . " {\n";
         $code .= "    var \$_mock;\n";
         $code .= $this->_addMethodList(array_merge($methods, $this->_reflection->getMethods()));
         $code .= "\n";
-        $code .= "    function " . $this->_mock_class . "() {\n";
+        $code .= "    function " . $constructor . "() {\n";
         $code .= "        \$this->_mock = &new " . $this->_mock_base . "();\n";
         $code .= "        \$this->_mock->disableExpectationNameChecks();\n";
         $code .= "    }\n";
@@ -1341,11 +1362,19 @@
      *    @access private
      */
     function _extendClassCode($methods) {
-        $code  = "class " . $this->_mock_class . " extends " . $this->_class . " {\n";
+        $code = "";
+        if (isset($this->_namespace)) {
+          $code .= "namespace " . $this->_namespace . ";\n";
+          $code .= "use ::" . $this->_mock_base . ";\n";
+          $constructor = "__construct";
+        } else {
+          $constructor = $this->_mock_class;
+        }
+        $code  .= "class " . $this->_mock_class . " extends " . $this->_class . " {\n";
         $code .= "    var \$_mock;\n";
         $code .= $this->_addMethodList($methods);
         $code .= "\n";
-        $code .= "    function " . $this->_mock_class . "() {\n";
+        $code .= "    function " . $constructor . "() {\n";
         $code .= "        \$this->_mock = &new " . $this->_mock_base . "();\n";
         $code .= "        \$this->_mock->disableExpectationNameChecks();\n";
         $code .= "    }\n";
This allows Mock classes to be generated from/inside namespaces.

For example, if you have a class file:

Code: Select all

<?php
 
namespace Foo;
 
class Interface Bar {
  public function doSometing();
}
Then you could have a test which mocks that interface in the correct namespace.

Code: Select all

<?php
 
namespace Foo;
 
use ::Mock;
use ::UnitTestCase;
 
Mock::generate('Foo::Bar', 'Foo::MockBar');
 
class SomeTest extends UnitTestCase {
  public function testSomething() {
    $mock = new MockBar();
    $mock->expectOnce('doSomething');
    $mock->doSomething();
  }
}

Re: [Patch] PHP 5.3 + namespaces + Mock objects

Posted: Wed Feb 20, 2008 8:07 pm
by Ambush Commander
Have you created a unit test for this? :-D

Re: [Patch] PHP 5.3 + namespaces + Mock objects

Posted: Wed Feb 20, 2008 8:30 pm
by Chris Corbyn
Meh! Unit Testing is dead to me! :P :lol:

No I haven't actually... I just threw it together in 5 mins. It's not really supposed to be a "proper" implementation... just a proof of concept ;)

Re: [Patch] PHP 5.3 + namespaces + Mock objects

Posted: Mon Feb 25, 2008 6:37 pm
by lastcraft
Hi...
Chris Corbyn wrote: No I haven't actually... I just threw it together in 5 mins.
Cheers for this :).

yours, Marcus