jeckel-lab / clock
时钟抽象库
1.2.0
2021-08-30 14:55 UTC
Requires
- php: ^7.2 || ^8.0
- jeckel-lab/contract: >=1.1
Requires (Dev)
- codeception/codeception: ^4.1
- mikey179/vfsstream: ^1.6
- phpmd/phpmd: ^2.9
- phpro/grumphp: ^0.19 || ^1.2.0
- phpunit/phpunit: ^8.5 || ^9.5
- roave/security-advisories: dev-master
- squizlabs/php_codesniffer: ^3.5
- vimeo/psalm: ^4.3
Suggests
- codeception/codeception: Use helper to handle clock with your codeception tests
README
时钟
PHP的时钟抽象库,允许在测试时模拟系统时钟
安装
composer require jeckel-lab/clock
使用
在你的代码中,当你需要访问当前时间时,始终使用JeckelLab\Contract\Infrastructure\System\Clock
接口在你的服务中。之后,你只需根据你的环境(真实或模拟)定义要使用的实现。
在某些框架中,使用工厂处理切换和注入所需配置可能更容易。
不同的模拟时钟
有2种类型的模拟时钟可用
frozen
:此时钟每次调用时总是返回相同的值faked
:此时钟将返回递增的时间(类似于真实时钟),但脚本开始时以定义的日期时间初始化。这对于继续跟踪长时间过程很有用。
模拟时钟可以以两种不同的方式启动
- 通过传递初始时间的值(配置中的
fake_time_init
值),此选项在你想始终使用相同的时间或使用环境变量初始化时很有用 - 通过传递包含时间值的文件的路径(配置中的
fake_time_path
)。此选项在你想在运行不同的测试用例时控制每个进程的时间时很有用。
与Symfony 4和5一起使用
在SF4和SF5中,我们使用内部DI系统与工厂。工厂将根据当前环境获取不同的参数。
在config/services.yaml
中配置DI的工厂
# config/services.yaml JeckelLab\Contract\Infrastructure\System\Clock: factory: ['JeckelLab\Clock\Factory\ClockFactory', getClock] arguments: ['%clock%']
在config/packages/parameters.yaml
中配置默认参数
# config/packages/parameters.yaml parameters: clock: mode: real timezone: Europe/Paris # Optional
然后配置测试环境中的参数,在config/packages/test/parameters.yaml
# config/packages/test/parameters.yaml parameters: clock: mode: faked fake_time_init: '2020-12-11 14:00:00'
或者
# config/packages/test/parameters.yaml parameters: clock: mode: frozen fake_time_path: '%kernel.project_dir%/var/test/fake_clock' fallback_to_current_date: true # Default: false, if true and file is not found or has invalid valid, then fallback to RealClock
使用Codeception进行测试
为了能够在Codeception测试中更改当前日期,你首先需要配置你的模拟时钟使用fake_time_path
文件作为时间源。
接下来,使用提供的助手配置codeception
# codeception.yaml # ... modules: config: \JeckelLab\Clock\CodeceptionHelper\Clock: fake_time_path: 'var/test/fake_clock' # Required: path where the fake time should be provided to your project date_format: 'Y/m/d' # Optional, date format for date value defined in your tests (default: Y/m/d) time_format: 'H:i:s' # Optional, time format for time value defined in your tests (default: H:i:s)
在你的测试套件中启用助手
# acceptance.suite.yml actor: AcceptanceTester modules: enabled: - \JeckelLab\Clock\CodeceptionHelper\Clock
现在你可以在你的测试中设置模拟时间
在BDD测试中
Feature: A feature description Scenario: A scenario description Given current date is "2021/03/26" and time is "08:35:00"
在其他测试中
/** @var \Codeception\Actor $i */ $I->haveCurrentDateAndTime('2021/03/26', '08:35:00'); // or $I->haveCurrentDateTime(DateTime::createFromFormat("Y/m/d H:i", "2021/03/26 08:35"));