【发布时间】:2015-08-10 09:14:36
【问题描述】:
假设我有一堂课:
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 库,则测试将失败,即使它可能会产生正确的结果
所以我可以单独测试这段代码吗?看起来我不能......这种依赖类型是否有一个不能被模拟的名称,因为它的行为本质上是被测试方法所必需的?
【问题讨论】:
-
为什么需要单独测试?
-
因为在实际用例中,如果测试失败,依赖项不是内置的(或 DomDocument),我不知道问题是否与我正在测试的方法的实现有关,或它构造的对象之一。当然,我可以对它们进行单独的测试,但是在开发过程中每次都运行所有测试是低效的。正如这里所说:msdn.microsoft.com/en-us/library/hh549175.aspx“通过隔离代码进行测试,您知道如果测试失败,原因就在那里,而不是其他地方”,如果测试被隔离,它只会使开发/调试更快。
标签: php unit-testing testing phpunit tdd