PHP单元测试 - 模拟静态自动加载类,带有嘲弄



我想单元测试官方段PHP集成的包装类。因此,我将不得不用嘲弄模拟细分市场,以便不会有任何真正的API请求。

问题

模拟的类仅由静态方法组成。因此,我试图像这样模拟它(与别名(:

$segment = Mockery::mock('alias:Segment');

这起作用,但前提是班级没有由作曲家自动加载。如果我加载它 - 就像我必须对应用程序的其余部分一样 - 我将获得错误

Could not load mock Segment, class already exists.

(这是有道理的,因为文档指出在之前不得加载别名类。(

问题

我如何嘲笑这个(邪恶?(班,但仍然像往常一样在我的应用程序中使用它?

本质上,您不能用静态调用模拟类。

静态调用始终准确地引用要调用的类和方法,这等同于指向要执行的文件和代码行(如果您假设基本自动加载功能可用(。

执行不同代码的唯一方法是不包括原始类,而是首先加载模拟类代码。您是否有替代代码文件,或者是使用嘲弄调用eval()都没有关系。两种方式都可以。

,但它们也只能工作一次。您不能在以后的测试中切换回原始代码,因为每次运行一次只能定义一类。并且无法切换实现(例如原始与模拟与另一个模拟(是问题所在。

该解决方案在评论中也提到:没有具有静态方法的类。始终创建类实例并调用动态方法。这样,您可以轻松模拟该类,但是它需要首先创建一个实例,并提供一种将类(或至少是模拟类(注入您要测试的代码的方法。

作为一种通用模式,如果项目中没有依赖项注入,我正在使用此

(我有时必须处理一些遗产的东西(:

public function __construct(MyClass $class = null) {
    $this->class = $class ?: new MyClass();
}

这样,我不必注入课程,但是我能够注入模拟而不是真实的班级。

对于可用依赖注入的情况,构造函数将是一个非常基本的初始化器:

public function __construct(MyClass $class) {
    $this->class = $class;
}

如果您的依赖注入框架能够进行自动接线(例如PHP-DI(,并且您只有一个MyClass,那么这效果很好,因为这将自动注入,而无需定义任何内容。

<</p> <</p>

最新更新