icanhazstring / symfony-time-machine
Symfony扩展包,用于更改应用程序的日期和时间功能
Requires
- php: ^8.1
- symfony/clock: ^6.2.x-dev
- symfony/dependency-injection: ^5.4 || ^6.1
- symfony/http-kernel: ^5.4 || ^6.1
Requires (Dev)
- ergebnis/composer-normalize: ^2.28
- phpstan/phpstan: ^1.8.9
- phpunit/phpunit: ^9.5.25
- roave/security-advisories: dev-master
- squizlabs/php_codesniffer: ^3.7.1
- symfony/framework-bundle: ^6.1
- symfony/yaml: ^6.1
- dev-main
- 0.1.1
- 0.1.0
- dev-dependabot/composer/symfony/dependency-injection-tw-6.3.8
- dev-dependabot/composer/symfony/http-kernel-tw-6.3.8
- dev-dependabot/github_actions/shivammathur/setup-php-2.27.1
- dev-dependabot/composer/phpstan/phpstan-tw-1.10.41
- dev-dependabot/composer/phpunit/phpunit-tw-10.4.2
- dev-dependabot/composer/ergebnis/composer-normalize-tw-2.39
- dev-dependabot/github_actions/actions/checkout-4
- dev-dependabot/composer/symfony/clock-tw-6.3.4
This package is auto-updated.
Last update: 2024-09-10 23:10:08 UTC
README
Symfony扩展包,用于更改应用程序的日期和时间功能
动机
编写应用程序的测试相对简单且容易。但针对基于大量DateTime
对象的测试怎么办呢?
已经有symfony/clock
提供了ClockInterface
接口,你可以用它注入NativeClock
或MockClock
到你的服务中。
但这只适用于测试。如果你想要进行端到端的测试呢?你可以更改服务器的系统时间,是的,但这有一个更简单的方法,就是使用这个symfony-time-machine
。
安装
composer require icanhazstring/symfony-time-machine
如果自动注册不起作用,将包添加到你的config/bundles.php
。
<?php return [ Icanhazstring\SymfonyTimeMachine\TimeMachineBundle => ['all' => true], ];
工作原理
此包依赖于你的应用程序中存在作为服务的ClockInterface
。因此,你需要在你的services.yaml
中添加类似以下内容
services: Symfony\Component\Clock\ClockInterface: class: Symfony\Component\Clock\NativeClock
此包将此服务设置为public: true
,因为这是在请求时更改服务所必需的。
现在每次启动TimeKernel
时,它将使用从请求查询/cookie中的time-machine
或环境变量TIME_MACHINE
中解析的日期时间字符串替换ClockInterface
。
使用方法
Web使用
对于Web使用,你需要稍微修改一下你的public/index.php
。
<?php use App\Kernel; use Icanhazstring\SymfonyTimeMachine\TimeKernel; require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; return function (array $context) { $kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']); (new TimeKernel($kernel))->fromContext($context)->boot(); return $kerneL; };
控制台使用
对于控制台使用,修改bin/console
。
return function (array $context) { $kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']); (new TimeKernel($kernel))->fromContext($context)->boot(); return new Application($kernel); };
注册额外的TimeMachineHandler
有时你需要修改应用程序中的其他服务,与time-machine一起。为此,你可以实现实现TimeMachineHandler
接口的服务。
这些服务将在容器中更改ClockInterface
之后被调用。`TimeKernel`将使用`HandlerRegistry`调用所有可用服务的`TimeMachineHandler::handle()`。
例如,你可以在你的应用程序中为所有openapi路径添加time-machine
查询参数,如这里使用api-platform所示。
final class PathModifier implements OpenApiPathModifier, TimeMachineHandler { public function __construct(private readonly OpenApiFactory $openApiFactory) { } public function handles(string $path, PathItem $pathItem): bool { return true; } public function modify(PathItem $pathItem): PathItem { /** @var array<string, null|Operation> $operations */ $operations = [ 'get' => $pathItem->getGet(), 'post' => $pathItem->getPost(), ]; foreach ($operations as $method => $operation) { if ($operation === null) { continue; } $queryParameters = $operation->getParameters(); $queryParameters[] = new Parameter( name: 'time-machine', in: 'query', description: 'Sets the applications datetime to a specific value.', required: false, schema: ['type' => 'string', 'default' => 'now'] ); $wither = 'with'.ucfirst($method); /** @var PathItem $pathItem */ $pathItem = $pathItem->{$wither}($operation->withParameters($queryParameters)); } return $pathItem; } public function handle(): void { $this->openApiFactory->addModifier($this); } }