Jasmine测试创建Order时违反外键约束报错 如何正确编写测试用例
订单模型创建测试外键约束问题解决方案
核心思路
要同时满足两个条件:一是创建订单前数据库存在对应关联的用户,符合外键约束要求;二是保证测试数据完全隔离,不会对其他测试文件的用例产生干扰。
具体实现步骤
- 第一步:在
order_spec.ts的测试块内配置生命周期钩子,每次测试执行前清空关联表数据、重置自增序列,保证每次测试的初始数据库环境完全干净
import { Client } from 'pg'; import { UserStore } from '../models/user'; // 初始化数据库客户端 const client = new Client({ // 你的数据库连接配置 }); describe('Order Model', () => { const store = new OrderStore(); const userStore = new UserStore(); beforeEach(async () => { // 先清空订单表,再清空用户表,避免触发外键删除约束 await client.query('DELETE FROM orders;'); await client.query('DELETE FROM users;'); // 重置两张表的自增ID序列,保证生成的ID符合断言预期 await client.query('ALTER SEQUENCE users_id_seq RESTART WITH 1;'); await client.query('ALTER SEQUENCE orders_id_seq RESTART WITH 1;'); }); // 其他测试用例... });
- 第二步:修改订单创建测试用例,先创建关联用户再执行订单创建操作
it('create method should add an order', async () => { // 先创建关联用户,满足外键约束条件 await userStore.create({ firstname: 'Test', lastname: 'User', password: 'testpass', role: 'user', email: 'test@test.com' }); const result = await store.create({ userId: 1, status: 'open', }); expect(result).toEqual({ id: 1, userId: 1, status: 'open', }); });
优化方案(可选)
如果不想每次测试都手动清空表,可以采用事务回滚的方式实现测试隔离,性能更高:
beforeEach(async () => { await client.query('BEGIN;'); }); afterEach(async () => { await client.query('ROLLBACK;'); });
事务模式下,测试过程中产生的所有数据都会在测试结束后直接回滚,不会真正写入数据库,也不会影响其他测试的执行结果。
注意事项
如果你的id字段是数据库自增主键,调用create方法时不需要手动传入id参数,数据库会自动生成,配合上面的序列重置操作,生成的ID会固定为1,和你的断言逻辑匹配。
内容的提问来源于stack exchange,提问作者Arefe
相关产品推荐
相关产品推荐

