Как смоделировать псевдоним класса с методом, который возвращает экземпляр себя? - PullRequest
5 голосов
/ 29 марта 2019

В последнее время я успешно использую Насмешка с тестами PHPUnit.Тем не менее, в проекте, над которым я сейчас работаю, есть зависимость, которая использует статические вызовы методов для взаимодействия с API.Я изо всех сил пытаюсь протестировать один конкретный вариант использования, и мне кажется, что я найду другой, подобный этому, во время дорожной карты разработки.

Используя этот класс в качестве примера:

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

В случаеЯ просто хочу утверждать, что метод возвращает тип примитива, такой как массив:

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

Он работает нормально, в первую очередь потому, что я не проверяю содержимое массива.

Однако ядолжен вызвать метод create, который возвращает экземпляр самого класса (User).Если я сделаю что-то вроде этого:

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

Псевдоним, очевидно, не будет работать, потому что класс уже был загружен через автозагрузчик (в данном случае это композитор).

Кто-нибудьесть предложения как это обойти?

Ответы [ 2 ]

2 голосов
/ 09 апреля 2019

А как насчет создания пользователя в замыкании?

<?php

$user = Mockery::mock('overload:\Name\Space\User')
    ->shouldReceive('create')
    ->andReturnUsing(function() {
              return new \Name\Space\User();
    });
0 голосов
/ 04 апреля 2019

Издеваться над статичными вещами всегда больно.Я бы порекомендовал создать объект Proxy, который вызывает статические вызовы API и просто возвращает результаты API, и внедряет этот объект везде, где вам нужно вызывать API.

Таким образом, это легко проверить, просто дразня проксиobject.

Затем сам прокси-объект может быть протестирован в сквозном тесте вне области чистого модульного тестирования.

Вы все еще можете делать более инвазивные вещи, такие как https://www.pagemachine.de/blog/mocking-static-method-calls/?cn-reloaded=1

Но написание кода, который не принадлежит вашим модульным тестам исключительно для того, чтобы сделать что-то тестируемое, мне не подходит.

...