我必须为使用由我们使用的apache扩展创建的资源类型的php类编写测试,但是假设它是具有mysql资源类型的数据库类。
显然我想模拟那些全局函数,但是当类检查资源是否创建好时,如何伪造返回类型?
php的doc资源页面甚至有一条评论抱怨模拟无法进行测试。这是最终答案吗?
让我说我有(蹩脚的例子)代码:
class DB {
function init(){
$this->handle = mysql_connect('myserver');
if( get_resource_type($this->handle) != 'mysql' ) return false;
return true;
}
}
然后通过模拟mysql_connect
来测试成功和失败的测试。
答案 0 :(得分:4)
也许你有点远。实际上,用PHP测试资源是完全没问题的,你可以得到他们的类型等等。
不容易测试的是它们所代表的依赖关系。你通常不注入那些,但你围绕这些资源编码。我们称之为反向导向的对象。
Central是对象(资源),在过程样式中属于它的代码始终具有该资源的依赖性。我们以curl为例:
$url = 'http://example.com/';
$handle = curl_init($url);
curl_exec($handle);
作为围绕$handle
对象的这种程序风格,如果curl是某些其他代码的依赖关系,那么在某种意义上用mock替换功能是不可模仿的。因此,您需要先将其包装起来以使其可注射:
$url = 'http://example.com/';
$curl = new Curl($url);
$curl->exec();
这需要在普通的旧PHP对象中转换以资源为中心的对象方向所需的价格:
class Curl
{
private $handle;
public function __construct($url) {
$this->handle = curl_init($url);
}
public function exec() {
return curl_exec($this->handle);
}
}
现在很容易嘲笑它。好处是,这通常是可能的,所以通常资源本身不应该对测试施加任何限制,它只是一些缺失的封装,所以你需要先添加它。
某些API(如imap扩展)由于全局静态而不允许创建干净的对象接口,在IMAP扩展的情况下,它是错误处理。但是它仍然越来越近,如果记录缺陷,这也有帮助。
答案 1 :(得分:1)
这可能会帮助那些试图模仿PHP函数的人,比如Curl:https://github.com/IcecaveStudios/isolator
它允许您将它们与代码隔离开来,使您能够使用正常的模拟技术。