cd ./docker
cp example.env .env
docker-compose up --build -d
Реализация тестов для классов UserStore (массив пользователей) и Validator (использование mock).
run tests:
docker exec -it phptests-php-cli vendor/bin/phpunit user_store/tests
Реализуем запись в файл всех посетителей приложения:
- имя пользователя, время посещения
В таком виде метод AuditManager::addRecord() тестировать сложно, потому что код логически не разделен и тесно связан с файловой системой:
run tests:
docker exec -it phptests-php-cli vendor/bin/phpunit audit/v1/tests
Типичное решение проблемы сильной связности тестов — создание мока для файловой системы.
Все операции с файлами выделяются в отдельный тип (IFileSystem), который внедряется в AuditManager через конструктор.
Затем в тесте мы используем мок типа (IFileSystem) и перехватываем методы обращения записи и чтения файлов.
То есть нам не нужно использовать реальную работу с файловой системой - используем Mock с настройкой его методов.
run tests:
docker exec -it phptests-php-cli vendor/bin/phpunit audit/v2/tests
Вместо того чтобы скрывать побочные эффекты за интерфейсом и внедрять этот интерфейс в AuditManager, можно полностью вынести эти побочные эффекты из класса.
В этом случае AuditManager будет отвечать только за принятие решения относительно того, что делать с файлами.
Новый класс Persister действует на основании этого решения и применяет обновления к файловой системе.
Persister в этом сценарии действует как изменяемая оболочка, тогда как AuditManager становится функциональным (неизменяемым) ядром.
run tests:
docker exec -it phptests-php-cli vendor/bin/phpunit audit/v3/tests
Мы изменили логику приводя к функциональной(гексагональной) архитектуре:
- переход от внепроцессной зависимости к использованию мока;
- переход от мока к функциональной архитектуре;