PHP-SimpleTest-列出对模拟对象方法的每次调用


PHP - SimpleTest - List every call to methods of a mock object

我的问题是,我需要列出对mock对象的每个调用,因为我需要检查它们。我在SimpleTest文档中没有找到任何关于此功能的信息。:S

也许还有另一种方法可以测试我的代码:

class Clean_Collection_Tree_NestedArrayParser {
    protected $path = array();
    protected $depth = -1;
    /** @var Clean_Collection_Tree_MapTreeInterface */
    protected $tree;
    public function setBasePath(array $path) {
        $this->path = $path;
    }
    public function setTree(Clean_Collection_Tree_MapTreeInterface $tree) {
        $this->tree = $tree;
    }
    public function parse($subject) {
        $this->parseArray($subject);
    }
    public function parseArray(array $array) {
        ++$this->depth;
        foreach ($array as $key => $value) {
            $this->path[$this->depth] = $key;
            if (is_array($value)) {
                $this->tree->put($this->path, new Clean_Collection_Map_Map());
                $this->parseArray($value);
            } else
                $this->tree->put($this->path, $value);
        }
        if (!empty($array))
            array_pop($this->path);
        --$this->depth;
    }
}

这是一个等待嵌套数组的解析器,我打算从中创建Map对象树。我用setTree(Clean_Collection_tree_MapTreeInterface$tree)注入实际的树,映射树接口为:

interface Clean_Collection_Tree_MapTreeInterface extends Clean_Collection_CollectionInterface {
    public function putAll(array $array);
    public function put(array $path, $value);
    public function get(array $path);
    public function getAll(array $pathes);
    public function removeAll(array $pathes);
    public function remove(array $path);
    public function contains(array $path);
}

解析器只使用put(array$path,$value)方法。因此,列出每个被调用的put方法将向我展示解析器中出现了什么问题。(如果SimpleMock没有这个功能,我可以创建我自己的mock对象,我们实现接口。我在上面。)

问题出在SimpleMock类设计中:

protected function addCall($method, $args) {
    if (! isset($this->call_counts[$method])) {
        $this->call_counts[$method] = 0;
    }
    $this->call_counts[$method]++;
}

他们应该创建一个记录器类来记录调用属性,而不是在SimpleMock。。。我们可以通过扩展SimpleMock类来创建一个变通方法:

class LoggedMock extends SimpleMock {
    protected $invokes = array();
    public function &invoke($method, $args) {
        $this->invokes[] = array($method, $args);
        return parent::invoke($method, $args);
    }
    public function getMockInvokes() {
        return $this->invokes;
    }
}

并将其设置为基本模拟类:

    require_once __DIR__.'simpletest/autorun.php';
    SimpleTest::setMockBaseClass('LoggedMock');

之后,我们可以使用$mockObj->getMockInvokes()获取调用列表。

编辑:我们不能扩展addCall,因为在invoke方法的第一行中,方法名被转换为lowerCase,所以通过扩展addCall我们只能记录lowerCase格式,而不能记录camelCase。(我认为小写转换是个错误…)

我创建了一个演示测试:

interface Nike {
    public function justDoIt();
}
class NikeUser {
    protected $nike;
    public function setNike(Nike $nike) {
        $this->nike = $nike;
    }
    public function doIt() {
        $this->nike->justDoIt();
    }
}
Mock::generate('Nike', 'MockNike');
class NikeUserTest extends UnitTestCase {
    public function testDoItButWeDontWantJustDoIt() {
        $mockNike = new MockNike();
        $nikeUser = new NikeUser();
        $nikeUser->setNike($mockNike);
        $expectedInvokes = array();
        $nikeUser->doIt();
        $expectedInvokes[] = array('justDoIt', array());
        $this->assertEqual($expectedInvokes, $mockNike->getMockInvokes());
    }
}