加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php – TDD – 不能嘲笑的依赖关系

发布时间:2020-12-13 13:58:08 所属栏目:PHP教程 来源:网络整理
导读:假设我有一个课程: class XMLSerializer { public function serialize($object) { $document = new DomDocument(); $root = $document-createElement('object'); $document-appendChild($root); foreach ($object as $key = $value) { $root-appendChild($d
假设我有一个课程:
class XMLSerializer {
    public function serialize($object) {
        $document = new DomDocument();
        $root = $document->createElement('object');
        $document->appendChild($root);

        foreach ($object as $key => $value) {
            $root->appendChild($document->createElement($key,$value);
        }

        return $document->saveXML();
    }

    public function unserialze($xml) {
        $document = new DomDocument();
        $document->loadXML($xml);

        $root = $document->getElementsByTagName('root')->item(0);

        $object = new stdclass;
        for ($i = 0; $i < $root->childNodes->length; $i++) {
            $element = $root->childNodes->item($i);
            $tagName = $element->tagName;
            $object->$tagName = $element->nodeValue();
        }

        return $object;
    }

}

如何隔离测试?测试这个类时,我也在测试DomDocument类

我可以传递文档对象:

class XMLSerializer {
    private $document;

    public function __construct(DomDocument $document) {
        $this->document = $document;
    }

    public function serialize($object) {
        $root = $this->document->createElement('object');
        $this->document->appendChild($root);

        foreach ($object as $key => $value) {
            $root->appendChild($this->document->createElement($key,$value);
        }

        return $this->document->saveXML();
    }

    public function unserialze($xml) {
        $this->document->loadXML($xml);

        $root = $this->document->getElementsByTagName('root')->item(0);

        $object = new stdclass;
        for ($i = 0; $i < $root->childNodes->length; $i++) {
            $element = $root->childNodes->item($i);
            $tagName = $element->tagName;
            $object->$tagName = $element->nodeValue();
        }

        return $object;
    }

}

这似乎解决了这个问题,但是现在我的测试并没有真的做任何事情.我需要做一个模拟的DomDocument返回我在测试中测试的XML:

$object = new stdclass;
$object->foo = 'bar';

$mockDocument = $this->getMock('document')
                ->expects($this->once())
                ->method('saveXML')
                ->will(returnValue('<?xml verison="1.0"?><root><foo>bar</foo></root>'));

$serializer = new XMLSerializer($mockDocument);

$serializer->serialize($object);

哪个有几个问题:

>我实际上并没有测试这个方法,所有我检查的是该方法返回$document-> saveXML()的结果,
>测试意识到方法的实现(它使用domdocument来生成xml)
>如果类重写为使用simplexml或另一个xml库,即使可以产生正确的结果,测试也将失败

所以我可以隔离测试这个代码?看起来我不能..这种类型的依赖关系的名称不能被嘲笑,因为它的行为本质上是被测试的方法所必需的?

这是关于TDD的问题. TDD意味着首先写测试.

我无法想象,在编写实际实现之前,先尝试一下嘲笑DOMElement :: createElement的测试.很自然,你从一个对象开始,并期待xml.

此外,我不会调用DOMElement依赖.这是您实施的一个私人细节.您将永远不会将不同的DOMElement实现传递给XMLSerializer的构造函数,因此不需要在构造函数中公开它.

测试也应作为文档.使用对象和预期的xml的简单测试将是可读的.每个人都可以阅读它,并确定你的班级正在做什么.比较这个50线测试与嘲笑(PhpUnit模拟是粗暴的冗长).

编辑:
这是一个很好的文章http://www.jmock.org/oopsla2004.pdf.
简而言之,它声明除非您使用测试来驱动您的设计(查找界面),否则使用嘲讽就没什么意义了.

还有一个很好的规则

Only Mock Types You Own

(在论文中提到)可以应用于你的例子.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读