cspray / database-test-case
用于断言数据库期望的PHPUnit测试用例
0.4.0
2024-04-05 13:33 UTC
Requires
- php: ^8.2
- phpunit/phpunit: ^10.0
Requires (Dev)
- ext-pdo: *
- ext-pdo_pgsql: *
- amphp/postgres: ^v2.0.0-beta.2
- roave/security-advisories: dev-latest
Suggests
- ext-pdo: To enable the PdoConnectionAdapter
- amphp/postgres: To enable the AmpPostgresConnectionAdapter
README
一个库,用于通过PHPUnit 10+简化数据库交互测试。
该库目前提供以下特性
- 处理典型的数据库设置和清理
- 简单表示表的行
- 为每个测试加载特定测试数据机制
该库目前尚未提供但计划提供以下特性
- 对数据库状态的语义断言
- 给定表的元信息表示
本文件的其余部分详细说明了如何安装此库,使用其TestCase
,以及支持哪些数据库连接对象。
安装
Composer 是安装此库的唯一支持方法。
composer require --dev cspray/database-test-case
使用指南
使用此库首先创建一个扩展Cspray\DatabaseTestCase\DatabaseTestCase
的PHPUnit测试用例。该类重写了PHPUnit提供的各种设置和清理函数,以确保建立数据库连接,并在已知状态下进行数据库交互。DatabaseTestCase
要求实现提供Cspray\DatabaseTestCase\ConnectionAdapter
。此实现最终负责对数据库的调用,由测试框架要求。该ConnectionAdapter
还提供了访问底层连接(例如,PDO
实例)的方法,您可以在测试代码中使用。请参阅“数据库连接”部分,了解支持的ConnectionAdapter
实例以及如何实现您自己的。
在我们的示例中,假设您有一个具有以下DDL的PostgreSQL数据库表
CREATE TABLE my_table (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(255),
email VARCHAR(255),
is_active BOOLEAN
)
现在,我们可以编写一系列与数据库交互的测试。
<?php declare(strict_types=1); namespace Cspray\DatabaseTestCase\Demo; use Cspray\DatabaseTestCase\DatabaseRepresentation\Row;use Cspray\DatabaseTestCase\DatabaseTestCase; use Cspray\DatabaseTestCase\LoadFixture;use Cspray\DatabaseTestCase\SingleRecordFixture;use PDO; class MyDemoTest extends DatabaseTestCase { // Generally speaking you shouldn't call this method yourself! protected static function getConnectionAdapter() : ConnectionAdapter { // Be sure to change these configuration values to match your test setup! return new PdoConnectionAdapter( new ConnectionAdapterConfig( database: 'postgres', host: 'localhost', port: 5432, user: 'postgres', password: 'postgres' ), PdoDriver::Postgresql ); } public function testUnderlyingConnection() : void { // You'd pass the value of this method into your code under test // Use a different ConnectionAdapter if you aren't working with PDO! self::assertInstanceOf(PDO::class, self::getUnderlyingConnection()); } public function testShowEmptyTable() : void { // DatabaseTestCase provides a method to get a representation of a database table $table = $this->getTable('my_table'); // The $table is Countable, the count represents the number of rows in the table self::assertCount(0, $table); // The $table is iterable, each iteration yields a Row, but our database is empty! self::assertSame([], iterator_to_array($table)); } // Pass any number of Fixture to have corresponding FixtureRecords inserted into // the database before your test starts #[LoadFixture( new SingleRecordFixture('my_table', ['username' => 'cspray', 'email' => 'cspray@example.com', 'is_active' => true]), new SingleRecordFixture('my_table', ['username' => 'dyana', 'email' => 'dyana@example.com', 'is_active' => true]) )] public function testLoadingFixtures() : void { $table = $this->getTable('my_table'); self::assertCount(2, $table); self::assertContainsOnlyInstancesOf(Row::class, iterator_to_array($table)); self::assertSame('cspray', $table->getRow(0)->get('username')); self::assertSame('dyana@example.com', $table->getRow(1)->get('email')); self::assertNull($table->getRow(2)); } }
测试用例钩子
DatabaseTestCase
必须处理几个关键事项,以确保数据库测试正常工作。为此,我们必须在所有通常使用的PHPUnit TestCase
钩子中做些事情。为了清楚起见,这些方法是
TestCase::setUpBeforeClass
TestCase::setUp
TestCase::tearDown
TestCase::tearDownAfterClass
为了确保DatabaseTestCase
正确处理这些钩子,它们已被标记为final
。还提供了新的方法,允许进行相同的有效钩子。