ВНУТРЕННИЙ
composer require --dev proklung/phpunit-testing-tools
Создать класс:
использовать ProklTestingToolsBaseBaseTestCase; использовать ProklTestingToolsToolsContainerBuildContainer; класс ContainerAwareBaseTestCase расширяет BaseTestCase {/** * @inheritDoc * @throws Exception */protected function setUp(): void{$this->container = static::$testContainer = BuildContainer::getTestContainer( ['dev/test_container.yaml','dev/local.yaml'],'/Resources/config', [new SampleCompilerPass()], // Опциональный параметр - кастомные проходы компилятора,'dev', // Окружение. По умолчанию - devtrue // Отладка. По умолчанию - true,['service_to_mock'] // Сервисы, нестандартные мокингу (см. подразделение Моки сервисов));parent::setUp(); } }
Отна проводит от него тест.
Подгружаются конфиги сервисов из указанных файлов по указанному пути (относительно тестов DOCUMENT_ROOT).
Механизм (на базе создания прокси-сервисов по заданному списку) взят из бандла и адаптирован под местные нужды.
использовать ProklTestingToolsToolsServiceMocker; использовать ProklTestingToolsBaseTestCase; класс MyTest расширяет BaseTestCase {use RestoreServiceContainer;защищенная функция setUp(): void{parent::setUp(); $this->container = BuildContainer::getTestContainer( ['test_container.yaml'],'/../../../../tests/Standalone/Resource/config', [],'dev', правда, ['filesystem.local.adapter'] // Сервис, который будет заменен моком.); }публичная функция testFoo() {// Для всех вызовов ServiceMock::all($this->container->get('filesystem.local.adapter'), 'getAdapter', function () { return new Local( $_SERVER['DOCUMENT_ROOT'] . ' /тест/'); }); $result = $this->container->get('filesystem.local.adapter');// Только для следующего вызова ServiceMock::next($this->container->get('filesystem.local.adapter') , 'getAdapter', function () { return new Local($_SERVER['DOCUMENT_ROOT'] . '/test/'); }); // Это поставит в очередь новый вызываемый ServiceMock::next($this->container->get('filesystem.local.adapter'), 'getAdapter', function () { throw new InvalidArgument('getAdapter может вызвать один раз! '); });$mock = // создаем макет PHPUnit или любой другой макет, который вам нужен.ServiceMocker::swap($this->container->get('filesystem.local.adapter'), $mock);// .. . $service = $this->container->get('filesystem.local.adapter'); $result = $service->getAdapter(); // Метод сервиса (или сервисного обслуживания) заменен. }protected function TearDown(): void{// Чтобы убедиться, что мы не влияем на другие тестыServiceMock::resetAll();// Вы можете включить признак RestoreServiceContainer для автоматического сброса сервисов} }
используйте ProklTestingToolsTraitsBootTestKernelTrait;класс ПримерТест расширяет ProklTestingToolsBaseBaseTestCase {use BootTestKernelTrait; защищенная функция setUp(): void {parent::setUp();$container = new ContainerBuilder(); // ... Наполнение тестового контейнера.self::$kernel = $this->bootTestKernel($container); } }
Базовый класс для тестирования консольных команд.
Методы:
executeCommand(Command $commandInstance, string $commandName, array $params = [])
— вернет то, что команда вывела на экран.
runCommand(Command $command, $input = [])
- вернет результат выполнения метода execute
команды.
Несколько найденных дата-провайдеров
provideEmptyValue
— пустые значения.
provideEmptyScalarValue
— пустые скалярные значения
provideBooleanValue
- булавочные значения
provideDateTimeInstance
— экземпляр DateTime
provideNotExistingFilePath
— путь к несуществующему файлу
Обертка над.
Пример (в тесте, ненаследованном от BaseTestCase
):
// Замыкается полностью (т.е. не важно, с какими параметрами происходит вызов) function in_the_loop $this->mockerFunctions->setNamespace('TestsAPI') ->full('in_the_loop', правда) -> макет();
Namespace
— пространство имен, в котором мокается функция.
Или частичное моканье (в зависимости от аргументов):
// При вызове get_cat_name с аргументом $this->idCategory вернет Имитируемая категория $this->mockerFunctions->setNamespace('TestAPIEntity') ->partial('get_cat_name', 'Высмеиваемая категория', $this->idCategory) ->partial('category_description', 'Описание высмеиваемой категории', $this->idCategory) -> макет();
При использовании этой фичи рекомендуется (во избежание проблем) в тест поставить аннотации:
/** * data() * * @runInSeparateProcess * @preserveGlobalState отключен */
Конструктор сервис-локаторов Symfony для тестов.
Метод:
constructServiceLocator(array $config)
- где $config
вид массива:
$object = new ClassName();$config = [ 'service_key' => ClassName::class, 'service_key2' => $object, ];
Если передать название класса в конфиге, то внутри метода класса будет организован.
Вилка-пакет
использовать AppCommandCreateUserCommand; использовать ProklTestingToolsBaseBaseTestCase; использовать ProklTestingToolsToolsConsoleInteractsWithConsole; использовать ProklTestingToolsTraitsBootTestKernelTrait; класс CreateUserCommandTest расширяет BaseTestCase {use InteractsWithConsole; используйте BootTestKernelTrait; защищенная функция setUp(): void{parent::setUp();$container = new ContainerBuilder();$container->setDefinition( IntegrityCheck::class,new Definition(IntegrityCheck::class, []) )->setTags(['console.command' => ['command' => 'module:еуые']])->setPublic(true);self::$kernel = $this->bootTestKernel($container); $this->cliApplication = новый SymfonyBundleFrameworkBundleConsoleApplication(self::$kernel);$this->cliApplication->add($container->get(IntegrityCheck::class)); } Публичная функция test_can_create_user(): void{$this->executeConsoleCommand('create:user kbond --admin --role=ROLE_EMPLOYEE --role=ROLE_MANAGER') ->assertSuccessful() // код завершения команды: 0->assertOutputContains('Создание администратора "kbond"') ->assertOutputContains('с ролями: ROLE_EMPLOYEE, ROLE_MANAGER') ->assertOutputNotContains('обычный пользователь') ;// расширенное использование$this->consoleCommand(CreateUserCommand::class) // можно использовать команду class или "name"->splitOutputStreams() // по умолчанию объединяются stdout/stderr, эта опция разделяет их->addArgument( 'кбонд') ->addOption('--admin') // с префиксом "--" или без него->addOption('role', ['ROLE_EMPLOYEE', 'ROLE_MANAGER']) ->addOption('-R') // для параметров быстрого доступа требуется префикс "-"->addOption('-vv') // по умолчанию вывод имеет нормальную многословность, для изменения используйте стандартные параметры (-q, -v , -vv, -vvv)->addOption('--ansi') // по умолчанию вывод не украшен, используйте эту опцию для украшения->execute() // запускаем команду->assertSuccessful() ->assertStatusCode(0) // эквивалент ->assertSuccessful()->assertOutputContains('Создание администратора "kbond"') ->assertErrorOutputContains('this is in stderr') // используется вместе с ->splitOutputStreams()->assertErrorOutputNotContains('admin user') // используется вместе с ->splitOutputStreams()->dump() // дамп () код состояния/выходные данные и continue->dd() // dd() код состояния/выходные данные;// интерактивное тестирование команды $this->executeConsoleCommand('create:user', ['kbond']) ->утверждениеУспех() ->assertOutputContains('Создание обычного пользователя "kbond"') ; // интерактивные команды расширенного тестирования $this->consoleCommand(CreateUserCommand::class) ->addInput('kbond') ->addOption('--no-interaction') // команды выполняются в интерактивном режиме, если предоставлен ввод, используйте эту опцию, чтобы отключить->execute() ->утверждениеУспех() ->assertOutputContains('Создание обычного пользователя "kbond"') ; // результат доступа $result = $this->executeConsoleCommand('create:user');$result->statusCode();$result->output(); $result->errorOutput(); } }
Или:
использовать AppCommandCreateUserCommand; использовать PHPUnitFrameworkTestCase; использовать ProklTestingToolsToolsConsoleTestCommand; класс CreateUserCommandTest расширяет TestCase {публичная функция test_can_create_user(): void{ TestCommand::for(new CreateUserCommand(/** args... */)) ->splitOutputStreams() // по умолчанию stdout/stderr объединяются, эта опция разделяет их->addArgument('kbond') ->addOption('--admin') // с префиксом "--" или без него->addOption('role', ['ROLE_EMPLOYEE', 'ROLE_MANAGER']) ->addOption('-R') // для параметров быстрого доступа требуется префикс "-"->addOption('-vv') // по умолчанию вывод имеет нормальную многословность, для изменения используйте стандартные параметры (-q, -v , -vv, -vvv)->addOption('--ansi') // по умолчанию вывод не украшен, используйте эту опцию для украшения->execute() ->утверждениеУспех() ->assertStatusCode(0) // эквивалент ->assertSuccessful()->assertOutputContains('Создание администратора "kbond"') ->assertErrorOutputContains('this is in stderr') // используется вместе с ->splitOutputStreams()->assertErrorOutputNotContains('admin user') // используется вместе с ->splitOutputStreams()->dump() // дамп () код состояния/выходные данные и continue->dd() // dd() код/выходные данные состояния; // тестирование интерактивных командTestCommand::for(new CreateUserCommand(/** args... */)) ->addInput('kbond') ->addOption('--no-interaction') // команды выполняются в интерактивном режиме, если предоставлен ввод, используйте эту опцию, чтобы отключить->execute() ->утверждениеУспех() ->assertOutputContains('Создание обычного пользователя "kbond"') ;// доступ result$result = TestCommand::for(new CreateUserCommand(/** args... */))->execute();$result->statusCode();$result->output(); $result->errorOutput(); } }
класс МойКласс {частная строка $privateProperty = 'частное значение';частная функция PrivateMethod(): string{return 'частное возвращаемое значение'; } }$myClass = новый Myclass();
Вот как вы можете получить стоимость частной собственности, используя функцию invade
.
вторгнуться ($myClass)->privateProperty; // возвращает "частное значение"
Функция invade
также позволяет вам изменять частные значения.
вторгнуться($myClass)->privateProperty = 'измененное значение';invade($myClass)->privateProperty; // возвращает 'измененное значение
Используя invade
вы также можете вызывать частные функции.
вторгнуться ($myClass)->privateMethod(); // возвращает «частное возвращаемое значение»