{"id":15450341,"url":"https://github.com/mekras/symfony-bundle-testing","last_synced_at":"2026-03-02T12:47:43.455Z","repository":{"id":246743370,"uuid":"821400736","full_name":"mekras/symfony-bundle-testing","owner":"mekras","description":"Инструменты для тестирования кода для Symfony","archived":false,"fork":false,"pushed_at":"2024-07-04T17:09:50.000Z","size":38,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-20T22:10:04.353Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mekras.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-06-28T13:05:13.000Z","updated_at":"2024-07-31T13:34:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"4da4a7f3-9461-40e2-b576-904dad106258","html_url":"https://github.com/mekras/symfony-bundle-testing","commit_stats":null,"previous_names":["mekras/symfony-bundle-testing"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mekras%2Fsymfony-bundle-testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mekras%2Fsymfony-bundle-testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mekras%2Fsymfony-bundle-testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mekras%2Fsymfony-bundle-testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mekras","download_url":"https://codeload.github.com/mekras/symfony-bundle-testing/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240822591,"owners_count":19863302,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-01T21:04:37.975Z","updated_at":"2026-03-02T12:47:43.403Z","avatar_url":"https://github.com/mekras.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Инструменты для тестирования пакетов Symfony\n\nЭта библиотека предоставляет инструменты для автоматизированного тестирования пакетов (bundles)\nSymfony.\n\n## Оглавление\n\n- [Установка](#установка)\n    - [Требования](#требования)\n    - [Установка через Composer](#установка-через-composer)\n- [Интеграционные тесты](#интеграционные-тесты)\n    - [Основной класс интеграционных тестов](#основной-класс-интеграционных-тестов)\n    - [Определение имени главного класса вашего пакета](#определение-имени-главного-класса-вашего-пакета)\n    - [Написание тестов](#написание-тестов)\n    - [Как проверить, что в контейнере есть нужна служба?](#как-проверить-что-в-контейнере-есть-нужна-служба)\n    - [Как получить службу из контейнера?](#как-получить-службу-из-контейнера)\n    - [Как добавить другие пакеты в контейнер?](#как-добавить-другие-пакеты-в-контейнер)\n    - [Как устранить ошибку «service or alias has been removed or inlined»?](#как-устранить-ошибку-service-or-alias-has-been-removed-or-inlined)\n\n## Установка\n\n### Требования\n\n- PHP 7.4+\n- Symfony 5.4+\n\n### Установка через Composer\n\nВ консоли в корне проекта выполните команду:\n\n    composer require --dev mekras/symfony-bundle-testing\n\n## Интеграционные тесты\n\nИнтеграционные тесты позволяют проверить как в действительности будет вести себя ваш код во\nвзаимодействии с Symfony.\n\n### Основной класс интеграционных тестов\n\nРекомендуется в каждом проекте создавать отдельный основной класс для всех классов ваших\nинтеграционных тестов, как единую точку определения конфигурации тестов и добавления общих методов.\n\nЭтот класс должен быть унаследован от\n[BaseSymfonyIntegrationTestCase](src/BaseSymfonyIntegrationTestCase.php).\n\nПример — `tests/Integration/IntegrationTestCase.php`:\n\n```php\nnamespace Acme\\MyBundle\\Tests\\Integration;\n\nuse Mekras\\Symfony\\BundleTesting\\BaseSymfonyIntegrationTestCase;\n\nabstract class IntegrationTestCase extends BaseSymfonyIntegrationTestCase\n{\n}\n```\n\nВсе классы интеграционных тестов должны наследоваться либо от этого класса, либо от\n`BaseSymfonyIntegrationTestCase`.\n\n### Определение имени главного класса вашего пакета\n\nВажным элементом интеграционного тестирования пакета Symfony является знание его главного класса\n(`*Bundle`). За это отвечает метод `BaseSymfonyIntegrationTestCase::getBundleClass()`.\nЕсли вы следуете\n[соглашениям по именованию пакетов](https://symfony.com/doc/current/bundles/best_practices.html#bundles-naming-conventions),\nто `getBundleClass()` должен правильно определять и возвращать имя класса. Если же он этого не\nделает, можете переопределить его в своём `IntegrationTestCase`:\n\n```php\nnamespace Acme\\MyBundle\\Tests\\Integration;\n\nuse Acme\\MyBundle\\AcmeMyBundle;\nuse Mekras\\Symfony\\BundleTesting\\BaseSymfonyIntegrationTestCase;\n\nabstract class IntegrationTestCase extends BaseSymfonyIntegrationTestCase\n{\n    protected function getBundleClass(): string\n    {\n        return MyBundle::class;\n    }\n}\n```\n\n### Написание тестов\n\nКостяк теста выглядит так:\n\n```php\nnamespace Acme\\MyBundle\\Tests\\Integration;\n\nfinal class SomeTest extends SymfonyIntegrationTestCase\n{\n    public function testSomething(): void\n    {\n        // Создаём тестовый контейнер зависимостей:\n        $container = $this-\u003ecreateContainer();\n        \n        // Здесь можно настраивать контейнер зависимостей и задавать ожидания.\n        \n        // Компилируем контейнер, чтобы подготовить его к тестам:\n        $container-\u003ecompile();\n        \n        // Здесь можно писать утверждения.\n    }\n}\n```\n\nКак правило, вначале надо создать контейнер зависимостей, т. к. почти вся интеграция с Symfony\nведётся через него. Метод `$this-\u003ecreateContainer()` создаёт тестовый контейнер (он подробно описан\nниже), который будет являться основной ваших тестов.\n\nКонтейнер создаётся с минимально необходимой предварительной конфигурацией:\n\n- устанавливаются важные параметры `kernel.*`;\n- регистрируются пакеты, возвращаемые методом `getRequiredBundles()` (см. далее);\n- регистрируется тестируемый пакет, определяемый описанным выше методом `getBundleClass()`;\n- выполняется ряд других действий.\n\nПосле создания контейнера, но **до его компиляции** вы можете произвести с ним дополнительные\nдействия по настройке или задать ожидания, как будет описано ниже.\n\nДалее контейнер необходимо скомпилировать, чтобы привести его в состояние, соответствующее времени\nвыполнения приложения. Это делается методом `$container-\u003ecompile()`.\n\nПосле компиляции можно выполнить нужные действия по проверке получившегося контейнера.\n\nНиже эти вопросы будут рассмотрены подробнее.\n\n### Тестовый контейнер зависимостей\n\nСердцем интеграционных тестов является контейнер зависимостей, позволяющий проверить правильность\nрегистрации в нём расширений вашего пакета, взаимодействие с ядром Symfony и/или другими пакетами.\n\nДля создания тестового контейнера используйте метод\n`BaseSymfonyIntegrationTestCase::createContainer`:\n\n```php\nfinal class SomeTest extends SymfonyIntegrationTestCase\n{\n    public function testSomething(): void\n    {\n        $container = $this-\u003ecreateContainer();\n\n        // …\n    }\n}\n```\n\nМетод создаст и вернёт новый экземпляр класса\n[TestContainerBuilder](src/DependencyInjection/TestContainerBuilder.php), расширяющего стандартный\n`ContainerBuilder` Symfony описанными ниже возможностями.\n\nВ одном тесте можно создать несколько независимых контейнеров.\n\n#### Загрузка расширений контейнера зависимостей\n\nМетод предназначен для тестирования расширений контейнера зависимостей Symfony и позволяет\nпроверить, правильно ли эти расширения загружаются, правильно ли настраивают контейнер.\n\n```php\npublic function testSomething(): void\n{\n    $container = $this-\u003ecreateContainer();\n    $container-\u003eloadExtension(new MyExtension());\n    $container-\u003ecompile();\n\n    self::assertTrue($container-\u003ehasExtension('my_extension_alias'));\n}\n```\n\n#### Загрузка в контейнер зависимостей других пакетов\n\n```php\npublic function testSomething(): void\n{\n    $container = $this-\u003ecreateContainer();\n    $container-\u003eregisterBundle(MonologBundle::class);\n    $container-\u003ecompile();\n\n    self::assertTrue($container-\u003ehasExtension('monolog'));\n}\n```\n\n### Как проверить, что в контейнере есть нужна служба?\n\nПредположим, ваш пакет должен зарегистрировать в контейнере службы с идентификаторами\n`some.service.id` и `щерук.service.id`. Проверить, что это действительно делается, можно так:\n\n```php\npublic function testFooServiceExists(): void\n{\n    $container = $this-\u003ecreateContainer();\n    $container-\u003eexpectDefinitionsExists(\n      'some.service.id',\n      'other.service.id',\n      // …\n    );\n    $container-\u003ecompile();\n    // Если не добавить эту строку, то PHPUnit может ругаться на отсутствие утверждений.\n    $this-\u003eexpectNotToPerformAssertions();\n}\n```\n\n### Как получить службу из контейнера?\n\nПубличные службы можно получить обычным способом — через метод `Container::get()`:\n\n```php\npublic function testSomething(): void\n{\n    $container = $this-\u003ecreateContainer();\n    $container-\u003ecompile();\n    \n    $someService = $container-\u003eget('some.service.id');\n    // Ваши проверки…\n}\n```\n\nПриватные службы можно получать через локатор или сделать публичными.\n\nПолучение через локатор:\n\n```php\npublic function testSomething(): void\n{\n    $container = $this-\u003ecreateContainer();\n    $this-\u003eaddToLocator(['some.private.service.id'], $container);\n    $container-\u003ecompile();\n    \n    $someService = $this-\u003egetFromLocator('some.private.service.id', $container);\n    // Ваши проверки…\n}\n```\n\nСделать публичной:\n\n```php\npublic function testSomething(): void\n{\n    $container = $this-\u003ecreateContainer();\n    $container-\u003emakePublic('some.private.service.id');\n    $container-\u003ecompile();\n    \n    $someService = $container-\u003eget('some.private.service.id');\n    // Ваши проверки…\n}\n```\n\n### Как добавить другие пакеты в контейнер?\n\nЕсли вы хотите протестировать интеграцию с другими пакетами, их можно добавить в тестовый контейнер\nс помощью метода `BaseSymfonyIntegrationTestCase::getBundleClass()`.\n\nДля одного теста это можно сделать непосредственно в нём между созданием и компиляцией контейнера:\n\n```php\npublic function testSomething(): void\n{\n    $container = $this-\u003ecreateContainer();\n    // Добавляет в контейнер MonologBundle:\n    $container-\u003eregisterBundle(MonologBundle::class);\n    $container-\u003ecompile();\n    \n    // Ваши проверки…\n}\n```\n\nЕсли это нужно для всех ваших тестов, то рекомендуется переопределить метод\n`createContainer` в основном классе:\n\n```php\nnamespace Acme\\MyBundle\\Tests\\Integration;\n\nuse Mekras\\Symfony\\BundleTesting\\BaseSymfonyIntegrationTestCase;\nuse Symfony\\Bundle\\MonologBundle\\MonologBundle;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\n\nabstract class IntegrationTestCase extends BaseSymfonyIntegrationTestCase\n{\n    protected function createContainer(array $public = []): ContainerBuilder\n    {\n        $container = parent::createContainer($public);\n\n        $container-\u003eregisterBundle(MonologBundle::class);\n\n        return $container;\n    }\n}\n```\n\nТак же есть возможность сразу задать список пакетов, которые надо загружать, переопределив метод\n`getRequiredBundles()`:\n\n```php\nnamespace Acme\\MyBundle\\Tests\\Integration;\n\nuse Mekras\\Symfony\\BundleTesting\\BaseSymfonyIntegrationTestCase;\nuse Symfony\\Bundle\\MonologBundle\\MonologBundle;\nuse Symfony\\Component\\DependencyInjection\\ContainerBuilder;\n\nabstract class IntegrationTestCase extends BaseSymfonyIntegrationTestCase\n{\n    protected function getRequiredBundles(): array\n    {\n        return \\array_merge(\n            parent::getRequiredBundles(),\n            [\n                MonologBundle::class,\n            ]\n        );\n    }\n}\n```\n\n### Как устранить ошибку «service or alias has been removed or inlined»?\n\nЕсли при извлечении из тестового контейнера вы столкнулись с такой ошибкой:\n\n\u003e The \"foo\" service or alias has been removed or inlined when the container was compiled.\n\u003e You should either make it public, or stop using the container directly and use dependency\n\u003e injection instead.\n\nто решить её можно сделав эту службу публичной, указав её в аргументе `$public` метода\n`createContainer()`:\n\n```php\npublic function testSomething(): void\n{\n    $container = $this-\u003ecreateContainer();\n    $container-\u003emakePublic('some.private.service.id');\n    $container-\u003ecompile();\n    \n    $someService = $container-\u003eget('some.private.service.id');\n    // Ваши проверки…\n}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmekras%2Fsymfony-bundle-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmekras%2Fsymfony-bundle-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmekras%2Fsymfony-bundle-testing/lists"}