Pull to refresh

Comments 15

Элегантно. Я вижу только один недостаток: после прогона теста в пространстве имен остается новая функция. Все будет хорошо, пока два разных теста в пределах одного неймспейса не захотят «замокать» функцию каждый по-своему.
Впрочем, наверняка можно как-то красиво и этот вопрос решить.
Я обычно выношу все подобные моки в отдельный файл (как helpers.php в примере), который подключается всеми заинтересованными тестами. Ну и внутри моков функций используется более сложная логика, покрывающая все потребности тестов. Тут уже всё зависит от сложности тестирования. Можно сделать класс со статическими членами, который будет и возвращать значения для моков функций, и вбрасывать исключения, и хранить историю вызовов. Всё ограничивается только фантазией программиста.
Тест после выполнения должен оставлять тестируемую систему ровно в том же виде, какой она была до запуска теста. В предложенном способе это условие нарушается, насколько я понимаю.
Почему? Вспомогательный класс не является частью тестируемой системы. Фактически это дополнение к классам PHPUnit.
Набор функций внутри неймспейса, в котором находится тестируемый класс, на мой взгляд является частью тестируемой системы. И этот набор меняется, когда тест завершает работу, т.к. в нем появляются новые функции.
Я не вижу в этом ничего страшного, если писать тесты с умом и не м́очить все функции подряд.
Тестируемая система не при чём.
Пространство имён определено в двух местах, в данном случае:
— в хелпере и самом тесте.
Хелпер подключается к тесту, для него и создан.

Каким образом это повлияет на систему?
А, понял, оно ж ещё и в src/MyClass.php, а это типа часть системы, да.
Красивое решение. Имеет полное право быть.
Возможно при реализации вылезут какие-то специфические проблемы, но хотя бы попробовать такое решение стоит.
Спасибо.
Да, это интересный подход. Есть еще один вариант — поставить на девелоп сервер APD. В нем есть функция переименования любой объявленной функции, даже системной. В итоге, мы можем делать что-то вроде

rename_function('fsockopen', '__dbg__fscokopen' );

function fscokopen(){
    // тут код для теста
    // вызов __dbg__fscokopen()
    // еще что-то...
}


В итоге во всем проекте все функции можно так вот прогонять через свои…
А как у APD обстоят дела с совместимостью с 5.3.3?
Красиво. Спасибо. С тестовыми данными, правда, надо подумать, чтобы это не превратилось в страшную кашу. Но, все равно, красиво.
Не могу понять как просто переопределить глобальную функцию в одном файле, чтобы это действовал на все подключаемые файлы. Или это невозможно будет сделать с помощью use в одном файле?
Пробую pastebin.com/B1FBgVLU, но в этом случае переопределённая функция не вызывается.
Sign up to leave a comment.

Articles