如何在Jest测试中用Sequelize种子文件初始化库并实现类Rake命令?
嘿,我来帮你搞定用Sequelize在Jest测试里复刻Knex那段数据库初始化逻辑,顺便聊聊怎么实现类Rake风格的命令~
用Sequelize在Jest中实现测试前的数据库初始化
我们可以借助Umzug(Sequelize官方迁移工具的底层依赖)直接在测试代码里调用迁移和种子操作,比调用CLI命令更优雅、更可控。
第一步:配置Umzug管理迁移和种子
先创建两个Umzug配置文件,分别管理迁移和种子(避免互相干扰):
迁移配置(umzug-migrate.js)
const { Sequelize } = require('sequelize'); // 导入你项目里已有的Sequelize实例,不要重复创建 const sequelize = require('./path-to-your-sequelize-instance'); const Umzug = require('umzug'); module.exports = new Umzug({ migrations: { path: './migrations', // 你的迁移文件目录 pattern: /\.js$/, params: [sequelize.getQueryInterface(), Sequelize] }, storage: 'sequelize', storageOptions: { sequelize, tableName: 'SequelizeMeta' // 默认的迁移记录表,无需修改 } });
种子配置(umzug-seed.js)
const { Sequelize } = require('sequelize'); const sequelize = require('./path-to-your-sequelize-instance'); const Umzug = require('umzug'); module.exports = new Umzug({ migrations: { path: './seeds', // 你的种子文件目录 pattern: /\.js$/, params: [sequelize.getQueryInterface(), Sequelize] }, storage: 'sequelize', storageOptions: { sequelize, tableName: 'SequelizeSeeds' // 自定义种子记录表,和迁移表区分开 } });
第二步:在Jest测试中编写beforeEach/afterEach
现在就可以在测试文件里调用这些配置好的Umzug实例,实现和Knex完全一致的逻辑:
const migrateUmzug = require('../umzug-migrate'); const seedUmzug = require('../umzug-seed'); describe('routes : movies', () => { // 测试前重置数据库 beforeEach(async () => { // 回滚所有迁移到初始状态 await migrateUmzug.down({ to: 0 }); // 运行最新的迁移 await migrateUmzug.up(); // 执行所有种子文件 await seedUmzug.up(); }); // 测试后清理数据库 afterEach(async () => { await migrateUmzug.down({ to: 0 }); }); // 你的测试用例写在这里 test('should return all movies', async () => { // ...测试逻辑 }); });
实现类Rake风格的命令
如果你想在命令行里快速执行数据库重置(类似Rake的db:reset),可以在package.json里添加脚本:
{ "scripts": { "db:migrate": "sequelize-cli db:migrate", "db:rollback": "sequelize-cli db:migrate:rollback --all", "db:seed": "sequelize-cli db:seed:all", "db:reset": "npm run db:rollback && npm run db:migrate && npm run db:seed" } }
现在你就可以像用Rake一样,运行npm run db:reset一键重置数据库,和测试里的初始化逻辑完全一致。
备选方案:直接调用Sequelize CLI命令
如果你不想用Umzug,也可以通过Node的child_process直接调用Sequelize CLI命令,不过这种方式依赖命令行环境,灵活性稍差:
const { execSync } = require('child_process'); describe('routes : movies', () => { beforeEach(() => { execSync('npx sequelize-cli db:migrate:rollback --all'); execSync('npx sequelize-cli db:migrate'); execSync('npx sequelize-cli db:seed:all'); }); afterEach(() => { execSync('npx sequelize-cli db:migrate:rollback --all'); }); });
内容的提问来源于stack exchange,提问作者Alex Miles
相关产品推荐
相关产品推荐

