cspray/database-test-case

用于断言数据库期望的PHPUnit测试用例

0.4.0 2024-04-05 13:33 UTC

This package is auto-updated.

Last update: 2024-09-05 14:32:15 UTC


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。还提供了新的方法,允许进行相同的有效钩子。

数据库连接