如何使用 returns 自身实例的方法模拟别名 class?

How to mock an aliased class with a method that returns an instance of itself?

我最近成功地使用 Mockery 进行 PHPUnit 测试。然而,我目前正在工作的项目中存在一个依赖项,它使用静态方法调用与 API 进行交互。我正在努力测试一个特定的用例,感觉我会在开发路线图中找到其他类似的用例。

以这个class为例:

namespace Name\Space;
class User
{
    /**
     * @return \Name\Space\User[]
     */
    public static function list(): array
    {
        // ...
    }
    public static function create(array $attrs): User
    {
        // ...
    }
}

如果我只想断言一个方法 returns 原始类型,例如数组:

Mockery::mock('alias:\Name\Space\User')
    ->shouldReceive('list')
    ->andReturn([]);

它工作正常,主要是因为我没有测试数组内容。

但是,我必须调用 create 方法,它 returns 是 class 本身的一个实例 (User)。如果我这样做:

$user = new \Name\Space\User();
Mockery::mock('alias:\Name\Space\User')
    ->shouldReceive('create')
    ->andReturn($user);

显然,别名不起作用,因为 class 已经通过自动加载器(在本例中为作曲家)加载。

有人对如何解决这个问题有建议吗?

模拟静态的东西总是很痛苦。 我建议创建一个调用静态 API 调用的 Proxy 对象,只调用 returns API 结果,然后在需要调用 API.[= 的任何地方注入这个对象11=]

这种方式很容易通过简单地模拟代理对象来测试。

然后可以在纯单元测试范围之外的端到端测试中测试代理对象本身。

你仍然可以像这样做更具侵入性的事情 https://www.pagemachine.de/blog/mocking-static-method-calls/?cn-reloaded=1

但是编写不属于您的单元测试的代码纯粹是为了让某些东西可测试对我来说并不合适。

在闭包中创建 User 怎么样?

<?php

$user = Mockery::mock('overload:\Name\Space\User')
    ->shouldReceive('create')
    ->andReturnUsing(function() {
              return new \Name\Space\User();
    });