You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PHPUnit中运行指定Phinx Seeder并获取生成的记录?

如何运行指定Phinx Seeder并获取生成的测试数据

场景说明

你已经实现了以下代码:

  • ManagerRole Seeder类,用于生成管理员用户数据
  • DatabaseTestCase PHPUnit基类,负责初始化测试数据库并运行迁移
  • MyTest测试类,继承自基类,需要运行指定Seeder并获取其生成的记录

你的现有代码

ManagerRole Seeder

use Phinx\Seed\AbstractSeed;

class ManagerRole extends AbstractSeed
{
    /**
     * Run Method.
     */
    public function run(): void
    {
        $prefix = microtime();
        $data = [
            [
                'email' => $prefix."@example.com",
                'password' => password_hash('1234', PASSWORD_DEFAULT),
                'active' => true,
                'fullname' => 'MANAGER Active'.$prefix,
                'role' => 'MANAGER'
            ],
            [
                'email' => $prefix."_inactive@example.com",
                'password' => password_hash('1234', PASSWORD_DEFAULT),
                'active' => false,
                'fullname' => 'MANAGER Inactive'.$prefix,
                'role' => 'MANAGER',
                'activation_token' => substr(base64_encode(random_bytes(12)), 0, 60) // 注意:原代码此处有多余分号,已删除
            ]
        ];

        $this->insert('users', $data);
    }
}

DatabaseTestCase基类

namespace Tests;

use App\Application;
use Phinx\Config\Config;
use Phinx\Migration\Manager;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;

class DatabaseTestCase extends TestCase {

    private $pdo;
    private $migrationManager;
    
    public function setUp ()
    {
        $migration_config = [
            'paths' => [
                'migrations' => __DIR__.'/../db/migrations',
                'seeds' => __DIR__.'/../db/seeds'
            ],
            'environments' => [
                'default_migration_table' => 'phinxlog',
                'default_environment' => 'testing',
                'testing' => [
                    'adapter' => 'mysql',
                    'host' =>  $_ENV['DB_HOST'],
                    'name' => $_ENV['DB_NAME'],
                    'user' => $_ENV['DB_USER'],
                    'pass' => $_ENV['DB_PASSWD'],
                    'port' => $_ENV['DB_PORT']??'3306',
                    'charset' => 'utf8',
                ],
            ],
            'version_order' => 'creation'
        ];

        $pdo = Application::createDB($migration_config['environments']['testing']);
        
        $config = new Config($migration_config);
        $manager = new Manager($config, new StringInput(' '), new NullOutput());
        $manager->migrate('testing');

        $this->pdo = $pdo;
        $this->pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);

        $this->migrationManager = $manager;
    }

    public function getMigrationManager()
    {
        return $this->migrationManager;
    }

    public function dbConnection()
    {
        return $this->pdo;
    }
}

解决方案

提供两种可行的实现方式,可根据需求选择:

方式一:修改Seeder暴露生成的数据

直接修改Seeder类,将生成的数据存储在公共属性中,测试时直接获取:

修改后的ManagerRole Seeder

use Phinx\Seed\AbstractSeed;

class ManagerRole extends AbstractSeed
{
    // 新增公共属性存储生成的种子数据
    public array $seededData = [];

    public function run(): void
    {
        $prefix = microtime();
        $this->seededData = [
            [
                'email' => $prefix."@example.com",
                'password' => password_hash('1234', PASSWORD_DEFAULT),
                'active' => true,
                'fullname' => 'MANAGER Active'.$prefix,
                'role' => 'MANAGER'
            ],
            [
                'email' => $prefix."_inactive@example.com",
                'password' => password_hash('1234', PASSWORD_DEFAULT),
                'active' => false,
                'fullname' => 'MANAGER Inactive'.$prefix,
                'role' => 'MANAGER',
                'activation_token' => substr(base64_encode(random_bytes(12)), 0, 60)
            ]
        ];

        $this->insert('users', $this->seededData);
    }
}

测试类中调用并获取数据

class MyTest extends DatabaseTestCase
{
    public function test()
    {
        // 实例化指定Seeder
        $seeder = new \ManagerRole();
        // 给Seeder注入数据库连接适配器
        $seeder->setAdapter($this->dbConnection());
        // 运行Seeder
        $seeder->run();
        // 获取生成的种子数据
        $seededValues = $seeder->seededData;

        // 示例断言:验证数据是否成功插入数据库
        $activeUser = $this->dbConnection()->query("SELECT * FROM users WHERE email = '{$seededValues[0]['email']}'")->fetch();
        $this->assertEquals($seededValues[0]['fullname'], $activeUser->fullname);
    }
}

方式二:通过Phinx Manager运行Seeder后查询数据库

如果不想修改Seeder,可以通过Phinx的MigrationManager运行指定Seeder,再通过数据库查询获取生成的记录:

测试类实现

class MyTest extends DatabaseTestCase
{
    public function test()
    {
        // 获取MigrationManager实例
        $manager = $this->getMigrationManager();
        // 运行指定Seeder:参数为环境名和Seeder类名
        $manager->seed('testing', 'ManagerRole');

        // 查询数据库获取生成的MANAGER角色记录
        $stmt = $this->dbConnection()->query("SELECT * FROM users WHERE role = 'MANAGER' ORDER BY active DESC");
        $seededValues = $stmt->fetchAll();

        // 示例断言
        $this->assertEquals(2, count($seededValues)); // 验证生成2条记录
        $this->assertTrue($seededValues[0]->active); // 验证第一条为激活状态
        $this->assertFalse($seededValues[1]->active); // 验证第二条为未激活状态
    }
}

注意事项

  • 原Seeder代码中最后一个数组元素的activation_token后有多余分号,会导致语法错误,需删除
  • 确保测试使用专用的测试数据库,避免污染生产数据
  • 方式一中若不想暴露公共属性,可添加getSeededData()方法返回数据

内容的提问来源于stack exchange,提问作者Dimitrios Desyllas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 21:02:10