Я отчаянно пытаюсь провести модульное тестирование модуля для системы магазинов. Эта система магазина использует статические методы, которые я должен вызывать в своих функциях, которые я хочу протестировать.
public function toTest() {
$value = \Context::getData();
return $value;
}
Теперь, как я могу модульно протестировать эту функцию, высмеивая этот статический вызов? Я пробовал использовать AspectMock, но это не сработало, потому что ему явно нужен доступ к исходному классу \ Context, который недоступен, поскольку это внешняя система. Я также попытался использовать class_alias для создания моего собственного класса Context, но это тоже не сработало, потому что мне нужны разные выходные данные Context в зависимости от того, какую функцию я тестирую. И установка class_alias несколько раз для разных тестов не работает, потому что один и тот же класс не может быть объявлен несколько раз, а @runTestsInSeparateProcesses не дала ожидаемого эффекта.
Обновлено: ни один из дубликатов не предоставил жизнеспособное решение моей ситуации, поэтому я не думаю, что это дубликат. Без доступа к коду торговой системы и особенно с таким сложным в обслуживании кодом, PHP не упрощает модульное тестирование. Также решение, которое я нашел, должно помочь другим с аналогичными настройками.
Возможный дубликат phpunit статический вызываемый метод в методе
Я не знаю, является ли это реалистичным примером вашего кода, но если это так, то здесь особо нечего тестировать. Вместо этого вам следует протестировать метод getData().
@DiogoSanto Этот дубликат предназначен для имитации метода, который был бы в моем собственном коде, а не во внешней системе, как здесь. По крайней мере, насколько я понимаю.
@jeroen Метод getData мне не принадлежит, поэтому я не могу его проверить. Также это очень упрощенный пример. Я делаю вещи с промежуточным значением $.
В этом случае я бы переместил вызов \Context::getData() в отдельный частный метод (почти как у вас сейчас ...), чтобы вы могли легко имитировать этот новый метод для тестирования вашего метода toTest().
@jeroen Спасибо за вашу помощь. Не могли бы вы дать мне небольшой пример кода, как бы я издевался над этим частным методом? У меня с этим серьезные проблемы.






Я мог решить свою проблему с помощью библиотеки 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
Поверьте, это дубликат Мокинг статических методов в PHP, который уже существует в stackoverflow.