Phpunit - Имитация внешних статических методов

Я отчаянно пытаюсь провести модульное тестирование модуля для системы магазинов. Эта система магазина использует статические методы, которые я должен вызывать в своих функциях, которые я хочу протестировать.

public function toTest() {
    $value = \Context::getData();
    return $value;
}

Теперь, как я могу модульно протестировать эту функцию, высмеивая этот статический вызов? Я пробовал использовать AspectMock, но это не сработало, потому что ему явно нужен доступ к исходному классу \ Context, который недоступен, поскольку это внешняя система. Я также попытался использовать class_alias для создания моего собственного класса Context, но это тоже не сработало, потому что мне нужны разные выходные данные Context в зависимости от того, какую функцию я тестирую. И установка class_alias несколько раз для разных тестов не работает, потому что один и тот же класс не может быть объявлен несколько раз, а @runTestsInSeparateProcesses не дала ожидаемого эффекта.

Обновлено: ни один из дубликатов не предоставил жизнеспособное решение моей ситуации, поэтому я не думаю, что это дубликат. Без доступа к коду торговой системы и особенно с таким сложным в обслуживании кодом, PHP не упрощает модульное тестирование. Также решение, которое я нашел, должно помочь другим с аналогичными настройками.

Поверьте, это дубликат Мокинг статических методов в PHP, который уже существует в stackoverflow.

Diogo Santo 26.11.2018 14:09

Возможный дубликат phpunit статический вызываемый метод в методе

Dirk Scholten 26.11.2018 14:09

Я не знаю, является ли это реалистичным примером вашего кода, но если это так, то здесь особо нечего тестировать. Вместо этого вам следует протестировать метод getData().

jeroen 26.11.2018 14:11

@DiogoSanto Этот дубликат предназначен для имитации метода, который был бы в моем собственном коде, а не во внешней системе, как здесь. По крайней мере, насколько я понимаю.

alobeejay 26.11.2018 14:18

@jeroen Метод getData мне не принадлежит, поэтому я не могу его проверить. Также это очень упрощенный пример. Я делаю вещи с промежуточным значением $.

alobeejay 26.11.2018 14:19

В этом случае я бы переместил вызов \Context::getData() в отдельный частный метод (почти как у вас сейчас ...), чтобы вы могли легко имитировать этот новый метод для тестирования вашего метода toTest().

jeroen 26.11.2018 14:21

@jeroen Спасибо за вашу помощь. Не могли бы вы дать мне небольшой пример кода, как бы я издевался над этим частным методом? У меня с этим серьезные проблемы.

alobeejay 26.11.2018 14:27
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
4
7
5 032
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я мог решить свою проблему с помощью библиотеки Mockery. Я попробовал несколько, но ничего не помогло. С Mockery теперь все кажется возможным. Очень помогла эта ссылка: https://robertbasic.com/blog/mocking-hard-dependencies-with-mockery/

Вы можете легко имитировать статические вызовы классов, которые вам не принадлежат:

public function methodToTest() {
    return \Context::getData();
}

public function testMethodToTest() {
    m::mock('alias:\Context')
        ->shouldReceive('getData')
        ->andReturn('foo');
}

И даже экземпляры классов, к которым у вас нет доступа:

public function methodToTest() {
    $obj = new \Category(5);
    return $obj->id;
}

public function testMethodToTest() {
    m::mock('overload:\Category')
        ->shouldReceive('__construct')
        ->with(5)
        ->andSet('id', 5);
}

Но вы должны помнить, что вам нужны две аннотации phpunit в начале класса:

* @runTestsInSeparateProcesses
* @preserveGlobalState disabled

Другие вопросы по теме