如何在PHPUnit中运行指定Phinx Seeder并获取生成的记录?
如何运行指定Phinx Seeder并获取生成的测试数据
场景说明
你已经实现了以下代码:
ManagerRoleSeeder类,用于生成管理员用户数据DatabaseTestCasePHPUnit基类,负责初始化测试数据库并运行迁移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
相关产品推荐
相关产品推荐

