icecave/isolator
Composer 安装命令:
composer require icecave/isolator
包简介
Dependency injection for global functions.
README 文档
README
Isolator simplifies testing of classes that make use of global functions by treating all global functions as methods on an "isolator" object.
composer require icecave/isolator
Rationale
A large number of PHP extensions (and the PHP core) implement their functionality as global functions. Testing classes that use these functions quickly becomes difficult due to the inability to replace them with test doubles.
Isolator endeavours to solve this problem by acting as a proxy between your class and global functions. An isolator instance is passed into your object as a dependency and used in place of any global function calls that you may want to replace when testing.
Example
The following class makes use of file_get_contents() to read the contents of a file.
class MyDocument { public function __construct($filename) { $this->filename = $filename; } public function getContents() { return file_get_contents($this->filename); } protected $filename; }
Despite the simplicity of the example, the class immediately becomes difficult to test due to it's reliance on the filesystem. In order to test this class you might be inclined to set up some static fixtures on disk, make a temporary directory when your test suite is set up or perhaps even use a virtual filesystem wrapper.
Isolator provides a fourth alternative. Given below is the same example rewritten using an Isolator instance.
use Icecave\Isolator\Isolator; class MyDocument { public function __construct($filename, Isolator $isolator = null) { $this->filename = $filename; $this->isolator = Isolator::get($isolator); } public function getContents() { return $this->isolator->file_get_contents($this->filename); } protected $filename; protected $isolator; }
MyDocument now takes an instance of Isolator in it's constructor. It would be a pain - and unnecessary - to create a
new Isolator instance every time you construct an object in your production code, so a shared instance is made
accessible using the Isolator::get() method. If a non-null value is passed to Isolator::get() it is returned
unchanged, allowing you to replace the isolator when necessary.
MyDocument::getContents() is also updated to use the isolator instance rather than calling the global function
directly. The behavior of MyDocument remains unchanged but testing the class is easy, as will be shown in the example
test suite below.
Note: The test below is written for the PHPUnit testing framework, using Phake for mocking. Phake provides a more flexible alternative to PHPUnit's built-in mock objects.
class MyDocumentTest extends PHPUnit\Framework\TestCase { public function setUp() { // First a mocked isolator instance is created ... $this->isolator = Phake::mock('Icecave\Isolator\Isolator'); // That isolator instance is given to the MyDocument instance // that is to be tested ... $this->myDocument = new MyDocument('foo.txt', $this->isolator); } public function testGetContents() { // Phake is used to configure the mocked isolator to return a known // string when file_get_contents() is called with a parameter equal // to 'foo.txt' ... Phake::when($this->isolator) ->file_get_contents('foo.txt') ->thenReturn('This is the file contents.'); // MyDocument::getContents() is called, and it's result checked ... $contents = $this->myDocument->getContents(); $this->assertEquals($contents, 'This is the file contents.'); // Finally Phake is used to verify that a call to file_get_contents() // was made as expected ... Phake::verify($this->isolator) ->file_get_contents('foo.txt'); } }
The test verifies the behavior of the MyDocument class completely, without requiring any disk access.
Using an isolator is most helpful when testing code that uses functions which maintain global state or utilize external
resources such as databases, filesystems, etc. It is usually unnecessary to mock out deterministic functions such as
strlen(), for example.
Isolator Trait
In PHP 5.4 and later, it is also possible to use IsolatorTrait to bring an isolator into your class. The isolator
instance is accessed using $this->isolator() and can be set via $this->setIsolator().
use Icecave\Isolator\IsolatorTrait; class MyDocument { use IsolatorTrait; public function __construct($filename) { $this->filename = $filename; } public function getContents() { return $this->isolator()->file_get_contents($this->filename); } protected $filename; }
Language Constructs
Isolator can also be used to invoke the following function-like language constructs:
include,include_once,requireandrequire_onceexitanddieechoevalnew
Peculiarities
Several of PHP's core global functions have some peculiarities and inconsitencies in the way they are defined. Isolator attempts to accomodate such inconsistencies when possible, but may have issues with some native C functions for which parameter reflection information is non-standard or incorrect. These issues seem to be largely rectified as of PHP 5.6.
icecave/isolator 适用场景与选型建议
icecave/isolator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.35M 次下载、GitHub Stars 达 35, 最近一次更新时间为 2012 年 08 月 05 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「phpunit」 「test」 「mock」 「stub」 「fake」 「unit」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 icecave/isolator 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 icecave/isolator 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 icecave/isolator 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
LazyPDO is a set of wrappers over PHP's standard PDO and PDOStatement classes. It enables lazy loading, serialization and decoration.
HiDev plugin for PHPUnit
Testing Suite For Lumen like Laravel does.
A cli tool which generates unit tests.
Mock PSR-18 HTTP client
Specification-oriented BDD helpers for PHPUnit
统计信息
- 总下载量: 1.35M
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 37
- 点击次数: 41
- 依赖项目数: 29
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2012-08-05