pr0ggy /
此包已被废弃,不再维护。没有建议替代包。
可模拟的单例行为特性
0.3
2016-07-16 23:58 UTC
Requires
- php: ^5.6.0|^7.0
Requires (Dev)
- peridot-php/peridot: ~1.15
This package is not auto-updated.
Last update: 2021-06-12 02:13:38 UTC
README
单例设计模式有其用途,但常常在客户端代码中被过度使用,使得单元测试变得困难。考虑一个临时的数据库查询示例
function executeQuery($query, $parameters) { $connection = DBConnectionPool::getInstance()->getConnection(); $statement_handle = $connection->executeQuery($query, $parameters) // ... return $result_rows; }
我们如何验证上述示例函数从连接池中获取连接,并验证返回的连接对象上调用的是预期方法?使用纯内部实例化的传统单例模式,由于无法替换 DBConnectionPool
实例为测试替身,测试将变得非常麻烦。
此特性通过暴露一些新方法来解决这个问题,这些方法实现了单例目标:限制实例化为单个实例,同时允许用测试替身替换实例。考虑以下使用测试框架(如 Peridot 和 pho)的 describe-it
语法的简单示例
describe('executeQuery($query, $parameters)', function () { $this->original_pool_instance = DBConnectionPool::getInstance(); $this->connection_pool_double = createConnectionPoolTestDouble(); function createConnectionPoolTestDouble() { // ... } beforeEach(function () { DBConnectionPool::unregisterSingletonInstance(); DBConnectionPool::registerSingletonInstance( $this->connection_pool_double ); }); afterEach(function () { DBConnectionPool::unregisterSingletonInstance(); DBConnectionPool::registerSingletonInstance( $this->original_pool_instance; ); }); it('should ask the DBConnectionPool singleton for a connection', function () { $this->connection_pool_double ->shouldReceive('getConnection') ->once(); $some_query = 'SELECT * FROM SOME_TABLE'; $some_parameters = []; executeQuery($some_query, $some_parameters); } ); it('should...', function () { // ... }); // ... });
在 src/MockableSingletonBehavior.php
中查看完整接口