【发布时间】:2016-12-23 11:41:49
【问题描述】:
我有一个方法,它打开一个套接字连接,使用,然后关闭它。为了使其可测试,我将处理连接转移到单独的方法中(参见下面的代码)。
现在我想为barIntrefaceMethod() 编写一个单元测试,并且需要模拟openConnection() 方法。换句话说,我需要一个假的resource。
是否有可能/如何在 PHP 中“手动”创建 resource 类型的变量(以伪造“opened files, database connections, image canvas areas and the like”等句柄)?
FooClass
class FooClass
{
public function barIntrefaceMethod()
{
$connection = $this->openConnection();
fwrite($connection, 'some data');
$response = '';
while (!feof($connection)) {
$response .= fgets($connection, 128);
}
return $response;
$this->closeConnection($connection);
}
protected function openConnection()
{
$errno = 0;
$errstr = null;
$connection = fsockopen($this->host, $this->port, $errno, $errstr);
if (!$connection) {
// TODO Use a specific exception!
throw new Exception('Connection failed!' . ' ' . $errno . ' ' . $errstr);
}
return $connection;
}
protected function closeConnection(resource $handle)
{
return fclose($handle);
}
}
【问题讨论】:
-
我不确定您是否以正确的方式处理此问题。如果我对您的理解正确,您实际上是想针对从
$resource->openConnection()返回的模拟/伪造资源对象测试 PHP 内置方法(fwrite、feof 等)。您应该考虑在这些方法周围使用一个包装器对象,以便您可以测试$resource->write('something')而不是fwrite($resource, 'something')。 -
感谢您的评论!不,当然,我不会不测试本机功能。而且,是的,我已经创建了包装连接设置相关 PHP 函数的方法。但是现在我想模拟他们的结果来测试
barIntrefaceMethod(),它调用了这些包装函数。问题只是,我找不到任何方法来伪造resource。这使嘲笑openConnection()感到沮丧。 -
我知道您不会测试本机函数,但您必须在代码中调用它们并且它们依赖于真实的资源句柄。最简单且设计更好的方法是让一个对象包裹在本机函数周围,然后模拟 that 。我将发布一个答案以更好地解释我在代码中的意思。
标签: php unit-testing mocking phpunit fsockopen