czukowski / phpunit-mock-dibi
Dibi mocking helpers for PHPUnit
Requires
- czukowski/phpunit-mock-db: ^7.0 || >= 8.2
- czukowski/phpunit-sql: ^7.0.2 || ^8.0 || ^9.0
- dibi/dibi: ~4.2.0
This package is auto-updated.
Last update: 2024-09-22 05:02:22 UTC
README
一个用于数据库查询测试的模拟对象库,无需从 fixtures 初始化内存数据库。相反,测试代码执行的每个查询都可以设置为返回预定义的结果集、受影响行数或最后插入 ID。所有这些都可以使用与 PHPUnit 模拟对象相似的熟悉界面。
这是 czukowski/phpunit-mock-db 包的修改版本,用于 David Grudl 的 Dibi - PHP 的智能数据库层。Dibi 是一个数据库连接库,包含一个强大的查询构建器,支持多种关系型数据库系统。
安装
使用 Composer 安装
composer require czukowski/phpunit-mock-dibi
- Dibi 版本 4.x 支持 PHP 7.2 或更高版本。
- Dibi 版本 3.x 支持 PHP 5.6 或更高版本。
用法
在一个测试用例类中使用 Cz\PHPUnit\MockDibi\MockTrait
特性,这将启用创建数据库模拟实例的方法。只需调用 createDatabaseMock
方法,传递一个使用本包提供的模拟驱动之一的 Dibi\Connection
实例,并将模拟对象添加到其中并注册到测试用例类。
在 Cz\PHPUnit\MockDibi\Drivers\DriversFactory
中有一个方便的模拟 Dibi 驱动程序工厂类,因此您无需自己创建驱动程序实例(请参阅其源代码以获取可用的方法)。
如何创建模拟 Dibi 连接的示例
$dibi = new Dibi\Connection([ 'driver' => $factory->createMySqlDriver() // or whatever other driver you may be needing. ]);
如何设置预期查询和模拟结果的示例
在 任何 数据库查询上返回预定义的结果集
$this->createDatabaseMock($dibi) ->expects($this->any()) ->willReturnResultSet([ ['id' => 1, 'name' => 'foo'], ['id' => 2, 'name' => 'bar'], ]);
在 任何 数据库查询上返回预定义的结果集,并期望它恰好执行一次
$this->createDatabaseMock($dibi) ->expects($this->once()) ->willReturnResultSet([ ['id' => 1, 'name' => 'foo'], ['id' => 2, 'name' => 'bar'], ]);
在每次特定数据库查询上返回预定义的结果集,期望每个查询恰好执行一次
注意:设置查询预期的顺序不必与查询执行的顺序相同。
另外注意:在查询约束中会忽略空格,因此可以从格式良好的文件中加载它们,这对于长且复杂的查询特别有用。
另外注意:不同的 Dibi 驱动程序可能使用不同的字符来引用标识符,例如 MySQL 中的反引号或 MS SQL Server 中的方括号等。查询约束将使用 Dibi Translator 转换查询,因此无需额外注意标识符引用是否匹配当前使用的驱动程序。
$mock = $this->createDatabaseMock($dibi); $mock->expects($this->once()) ->query('SELECT * FROM `t1`') ->willReturnResultSet([['id' => 1, 'name' => 'foo']]); $mock->expects($this->once()) ->query('SELECT * FROM `t2`') ->willReturnResultSet([['id' => 2, 'name' => 'bar']]);
期望混合查询,一些在特定调用中(注意:SELECT 查询设置为返回空结果集)
$mock = $this->createDatabaseMock($dibi); $mock->expects($this->at(1)) ->query('INSERT INTO `t1` VALUES (1, "foo")') ->willSetLastInsertId(1); $mock->expects($this->at(2)) ->query('INSERT INTO `t1` VALUES (2, "bar")') ->willSetLastInsertId(2); $mock->expects($this->once()) ->query('SELECT * FROM `t1`') ->willReturnResultSet([]);
期望相同的查询恰好执行三次,并在每次连续调用中返回不同的最后插入 ID
$this->createDatabaseMock($dibi) ->expects($this->exactly(3)) ->query('INSERT INTO `t1` VALUES ("a", "b", "c")') ->willSetLastInsertId(1, 2, 3);
返回受影响行数
$this->createDatabaseMock($dibi) ->expects($this->exactly(2)) ->query('UPDATE `t1` SET `foo` = "bar" WHERE `id` = 1') ->willSetAffectedRows(1);
使用 PHPUnit 约束匹配 SQL 查询(注意:当使用默认的 PHPUnit 约束时,将忽略空格)
$this->createDatabaseMock($dibi) ->expects($this->once()) ->query($this->stringStartsWith('SELECT')) ->willReturnResultSet([['id' => 1, 'name' => 'foo']]);
使用连续调用存根构建器为 INSERT 查询在连续调用上设置不同的结果
$this->createDatabaseMock($dibi) ->expects($this->exactly(4)) ->query($this->stringStartsWith('INSERT')) ->onConsecutiveCalls() ->willSetLastInsertId(1) ->willSetLastInsertId(2) ->willThrowException(new RuntimeException('Deadlock')) ->willSetLastInsertId(3);
尽管通常不需要,但可以设置自定义回调来处理数据库查询(回调不需要返回任何内容)
$mock = $this->createDatabaseMock($dibi); $mock->expects($this->any()) ->query($this->stringStartsWith('INSERT')) ->willInvokeCallback(function ($invocation) { $invocation->setLastInsertId(1); }); $mock->expects($this->any()) ->query($this->stringStartsWith('UPDATE')) ->willInvokeCallback(function ($invocation) { $invocation->setAffectedRows(0); }); $mock->expects($this->any()) ->query($this->stringStartsWith('SELECT')) ->willInvokeCallback(function ($invocation) { $invocation->setResultSet([]); });
默认情况下,模拟对象设置为在执行未知(不匹配)查询时抛出异常,但可以禁用此功能
$mock = $this->createDatabaseMock($dibi); $mock->setRequireMatch(FALSE);
许可证
本作品采用MIT许可证发布。详情请参阅LICENSE.md。