Скажем, у меня есть класс:
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;
}
}
Что, кажется, решает проблему, однако, теперь мой тест на самом деле ничего не делает. Мне нужно сделать mock 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, даже если он может привести к правильному результату.
так что я могу проверить этот код отдельно? Похоже, я не могу.. есть ли имя для этого типа зависимости, которое нельзя высмеять, поскольку его поведение по существу требуется для тестируемого метода?