如何模拟另一个类使用的全局函数和类

时间:2017-02-09 00:08:34

标签: php unit-testing testing phpunit

我正在尝试编写测试,我的一个方法使用了一个全局函数web(),它接受​​一个(字符串)url,并创建并返回UrlHelper的新实例。这为我的应用程序提供了一些辅助方法的快捷方式。 (是的DI会更好,但这是一个应用程序......)

我尝试测试的方法,使用此全局帮助程序获取给定网址的内容并将其与另一个字符串进行比较。

使用phpunit,我如何拦截对web的调用或UrlHelper的创建,以便我可以确保它返回给定的响应?代码看起来有点像下面的

function web($url){
 return new \another\namespace\UrlUtility($url);
}

...

namespace some/namespace;

class checker {
   function compare($url, $content){
       $content = web($url)->content();
       ...logic...
       return $status;
   }
}

单元测试正在测试比较的逻辑,所以我希望从web调用获得预期的内容。我希望模拟/存根可以解决这个问题 - 但是我不确定我是否可以使用这个全局函数或其他没有传入的类?

由于

3 个答案:

答案 0 :(得分:4)

您可以使用Mockery重载该类,然后更改该方法的实现。

$mock = \Mockery::mock('overload:'.HelperUtil::class);
$mock->shouldReceive('content')->andReturnUsing(function() {
    return 'different content';
});

答案 1 :(得分:1)

您可以在测试中重新声明命名空间中的全局函数,这将优先。

注意:它很脏。

答案 2 :(得分:0)

  1. 为您的网络实用程序定义一个很好的内聚界面。
  2. 将该全局函数重构为实现该接口的类。
  3. 将接口注入客户端类。您不需要任何框架。如果您的项目中没有 DI 容器,只需将其作为构造函数参数手动传递即可。
  4. 在测试环境中提供接口的模拟实现。