@JeanPaulBelmondo

Как тестировать функции у передаваемого объекта в phpunit?

Вопрос возможно не очень корректно указан, но постараюсь объяснить.

Есть такой код:
spoiler

public function extractStoreMainTheme(ShopModel $shop): void
    {
        $themesResponse = $shop->api()->rest('GET', '/admin/themes.json');

        if (!$themesResponse['errors'] && isset($themesResponse['body']['themes'])) {
            $themes = $themesResponse['body']['themes']->toArray();
            $key = array_search($this::MAIN_ROLE, array_column($themes, $this::THEME_FIELD));

            $this->mainTheme = MainTheme::fromNative($themes[$key]);
            $this->extractThemeAssets($shop);
        } else {
            $this->mainTheme = MainTheme::fromNative([]);
        }
    }



На входе у нас Eloquent модель Laravel - $shop.
И далее проблема, так как от магазина идёт запрос на внешний сервис, а там, конечно же, не тот ответ, который мне нужен.

Можно как-то подменить ответ от "$shop->api()->rest('GET', '/admin/themes.json')" ?
Попробовал создать мок объект, или заглушку, как-то не очень получилось.

ссылка на исходный класс


Да и как в целом такое тестировать? я имею виду классы с приватными полями и объекты у которых вложенные объекты имеют функции)
  • Вопрос задан
  • 58 просмотров
Решения вопроса 1
SilenceOfWinter
@SilenceOfWinter Куратор тега PHP
та еще зажигалка...
я имею виду классы с приватными полями
можно получить к ним доступ через ReflectionProperty::setAccessible()
объекты у которых вложенные объекты

Варианты в порядке убывания сложности:
  1. $themesResponse = $shop->api()->rest('GET', '/admin/themes.json');
    выносится в отдельный метод
  2. в тестах используем класс-наследник в котором переопределяем результат данного метода
  3. Создать класс-наследник ShopModel с переопределенным методом api возвращающим мок или класс-наследник BasicShopifyAPI.
  4. Использовать вложенное мокирование:
    $apiMock = $this->createMock(BasicShopifyAPI::class);
    $apiMock->method('rest')
         ->with($this->equalTo('GET'), $this->equalTo('/admin/themes.json'))
         ->willReturn(['errors' => [], 'body' => ['themes' => []]]);
    $shopMock = $this->createMock(ShopModel::class);
    $shopMock->method('api')->willReturn($apiMock);


Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы