【发布时间】:2013-09-25 16:08:18
【问题描述】:
目前我正在测试一个基于值对象生成 XML、通过 HTTP 发送 XML 并将 XML 响应解析回第二个值对象的类。在这种情况下,我想测试生成的 XML 和基于给定 XML 解析的值对象。
类看起来像:
class MyClient
{
public function send(RequestValues $request)
{
$document = $this->generateMessage($request);
$response = $this->request($document);
return $this->parseResponse($response);
}
protected function generateMessage(RequestValues $request)
{
$document = new DomDocument;
// Do stuff with $request
return $document;
}
public function request(DomDocument $document)
{
$client = $this->getHttpClient();
$client->setRawBody($document->saveXml());
// Configure client
return $client->send();
}
public function parseResponse(Response $response)
{
$parameters = new ResponseValues;
$document = new DomDocument;
$document->loadXml($response->getBody());
// Fill in $parameters
return $parameters;
}
}
我想测试两件事:
- 给定某个
RequestValues参数,生成的XML 必须看起来像$string - 给定某个 XML 响应值(HTTP 客户端将被模拟),
ResponseValues必须等于$object
我现在正在为#1 编写测试,但我认为我只能通过回调来实现这一点。然而,当测试失败时,回调并没有给我非常有用的信息。只有这条消息:
断言 DOMDocument Object () 被指定回调接受失败。
测试看起来像这样:
public function testRequestContainsValidXml()
{
$client = $this->getMock('MyClient', array('request'));
$message = '';
$client->expects($this->once())
->method('request')
->with($this->callback(function($object) use ($message) {
return
($object instanceof DomDocument)
&& ($object->saveXml() === $message);
}));
$request = new DirectoryRequest;
$client->send($request);
}
问题是:我怎样才能改进测试,以便可以进行正常的字符串比较?我很想让 phpunit 说“字符串 X 不等于 Y”,这极大地简化了调试。
附言。这个类的完整代码可以在 GitHub 上找到。当然,上面的例子是一个简化版本。这是实际的课程:https://github.com/juriansluiman/SlmIdealPayment/blob/master/src/SlmIdealPayment/Client/StandardClient.php#L58
PPS。如果必须更改代码才能对其进行测试,那不是问题。我只想保持公共 API 不变(即调用 ResponseValues send(RequestValues $request)
【问题讨论】:
-
到底是什么问题?是不是比较
$object->saveXml() === $message失败了? -
@silkfire 如果 $message 是正确的,它不会失败而只是通过。但是,无法查看预期字符串和实际字符串之间的差异。您无法通过单元测试以任何方式进行调试,这可以通过例如
$this->assertEquals($string1, $string2)。因此,单元测试可以帮助我理解代码中的错误,它是一个大黑匣子,如果您不小心遇到错误,它并没有真正的帮助。 -
所以问题是(也用粗体表示)我如何改进测试。我可以让它通过,但问题是当它没有通过时从 phpunit 获取有意义的消息。
-
有可供 PHP 使用的 diff 类,您可以使用它们来查看逐个字符的区别;那么你可以在单元测试中调用那个 diff 函数吗?
-
比如FineDiff 确实不错;在这里测试他们利用课程的工具:raymondhill.net/finediff/viewdiff-ex.php
标签: php unit-testing mocking phpunit