Как проверить сервис, который взаимодействует со сторонним API? - PullRequest
0 голосов
/ 16 января 2020

У меня есть следующий сервис, который я хочу протестировать:

namespace App\Service;

class ApiManager
{
   public function getProjects()
   {
      $projects = $this->pager->fetchAll(
                $this->client->api('projects'),
                'all',
                [['simple' => true]]
      );
   }
}

Сервис использует пакет Gitlab API для PHP. Таким образом, данные в $ projects выглядят так:

[
   0 => [
           'id' => 1,
           'title' => 'Project #1',
           'description' => 'Project description...'
        ],
   1 => [
           'id' => 2,
           'title' => 'Project #2',
           'description' => 'Project description...'
        ],
]

Конечно, я не хочу проверять реальные данные из API. Как я могу издеваться над данными, которые возвращаются из HTTP-запроса в getProjects?

Ответы [ 4 ]

1 голос
/ 16 января 2020

Я думаю, что вы ответите на свой вопрос Внедрение зависимостей .

Проще говоря, Внедрение зависимостей - это шаблон проектирования, который помогает избежать жестко запрограммированных зависимостей для некоторого фрагмента кода или программное обеспечение.

Ресурсы:

Что такое внедрение зависимостей?

1 голос
/ 16 января 2020

Выведите public function getProjects() в свой собственный сервис, например ProjectService, и внедрите его в свой ApiManager.

Создайте две версии ProjectService: ProjectService и ProjectMockService, в первую очередь для производства, 2-й должен вернуть ваши смоделированные значения ( все, что вам нужно здесь).

Затем поддержите services.yaml для prod и тестовых сред . В зависимости от активной среды будет введена правильная версия ProjectService.

0 голосов
/ 18 января 2020

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

Этот уровень абстракции облегчает тестирование, поскольку существует только одно место, где Используются данные API: в каком-то виде отображения. Класс обслуживания может извлечь данные из API, а преобразователь затем преобразует ответ (ы) в объекты домена.

В ответ на ваш реальный вопрос я бы не стал проверять HTTP-вызов API. Тестирование сетевых вызовов замедляет работу вашего набора тестов и приводит к сбою в среде без сетевого подключения. Вместо этого я протестировал бы маппер с предварительно сохраненным или фиктивным ответом от API. Если API в какой-то момент начинает возвращать данные в другой «форме», то в вашем коде есть только одно место для изменения (слой отображения).

0 голосов
/ 18 января 2020

В этом конкретном случае c вам не нужно ничего особенного. У вас уже есть Pager в качестве зависимости (которую, я надеюсь, вы получаете через __construct()). Если это так, просто go впереди и смоделируйте $this->pager->fetchAll() для модульного тестирования вашего метода.

Похоже на следующее:

ApiManagerTest. php

class ApiManagerTest extends TestCase
{
    private $pager;

    private $apiManager;

    public function setUp(): void
    {
        $this->pager = $this->prophesize(Pager::class);

        // Notice we pass the mocked `pager` object here
        $this->apiManager = new ApiManager(
            $this->pager->reveal()
        );
    }

    public function testGetProjects(): void
    {
        // Given
        $projects = $this->givenTwoProjectsExist();

        $this->pager->getProjects(
            'projects',
            'all',
            [['simple' => true]]
        )
        ->shouldBeCalledOnce()
        ->willReturn($projects);

        // When
        $result = $this->apiManager->fetchAll();

        // Then
        self::assertEquals($projects, $result);
    }
}

Подробнее о структуре «Задано, когда, потом» можно прочитать здесь: https://thephp.website/en/issue/clean-tests-with-php-and-phpunit/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...