Javascript 如何使用Jest/Supertest/Knex/Postgres处理外键约束
我正在尝试为我的应用程序编写测试。我正在使用Jest&Supertest来运行我的所有测试。当我尝试运行我的测试套件时,我得到一个关于外键约束的错误 错误:Javascript 如何使用Jest/Supertest/Knex/Postgres处理外键约束,javascript,node.js,postgresql,jestjs,knex.js,Javascript,Node.js,Postgresql,Jestjs,Knex.js,我正在尝试为我的应用程序编写测试。我正在使用Jest&Supertest来运行我的所有测试。当我尝试运行我的测试套件时,我得到一个关于外键约束的错误 错误: error: truncate "users" restart identity - cannot truncate a table referenced in a foreign key constrainterror: cannot truncate a table referenced in a foreign key constra
error: truncate "users" restart identity - cannot truncate a table referenced in a foreign key constrainterror: cannot truncate a table referenced in a foreign key constraint
这是我的server.spec.js文件:
const request = require('supertest');
const server = require('./server.js');
const db = require('../data/db-config.js');
describe('server.js', () => {
describe('POST /register', () => {
it('should return 201 created', async () => {
const user =
{
name: "test",
username: "test",
email: "test77@test.com",
password: "password"
}
const res = await request(server).post('/api/auth/register').send(user);
expect(res.status).toBe(201);
})
beforeEach(async () => {
await db("graphs").truncate();
await db("users").truncate();
});
})
})
这是我的knex迁移文件:
exports.up = function(knex) {
return (
knex.schema
.createTable('users', tbl => {
tbl.increments();
tbl.string('username', 255).notNullable();
tbl.string('password', 255).notNullable();
tbl.string('name', 255).notNullable();
tbl.string('email', 255).unique().notNullable();
})
.createTable('graphs', tbl => {
tbl.increments();
tbl.string('graph_name', 255).notNullable();
tbl.specificType('dataset', 'integer[]').notNullable();
tbl
.integer('user_id')
.unsigned()
.notNullable()
.references('id')
.inTable('users')
.onDelete('CASCADE')
.onUpdate('CASCADE');
})
)
};
exports.down = function(knex) {
return (
knex.schema
.dropTableIfExists('graphs')
.dropTableIfExists('users')
)
};
我在研究中发现了这个答案:
我对博士后和考试都是新手。我需要像迁移中一样按相反的顺序删除表,这是有道理的。但是,当我在测试的beforeach
部分中尝试截断它们时,表的列出顺序似乎并不重要
我不知道从这里到底要去哪里。任何帮助都将不胜感激。我想这里的诀窍是求助于一点
knex.raw
:
await db.raw('TRUNCATE graphs, users RESTART IDENTITY CASCADE');
CASCADE
是因为您不希望外键约束妨碍,而RESTART IDENTITY
是因为默认的Postgres行为不是重置序列。看
当我们讨论一个相关主题时,请允许我介绍一些可能会让您的生活更轻松的东西:模板数据库!模板是Postgres可以用来从已知状态(通过复制)非常快速地重新创建数据库的数据库。这甚至比截断表还要快,而且它允许我们在测试时跳过所有恼人的外键
例如,您可以使用raw
执行以下操作:
DROP DATABASE testdb;
CREATE DATABASE testdb TEMPLATE testdb_template;
这是一个非常便宜的操作,非常适合测试,因为每次运行测试时都可以从已知状态(不一定是空状态)开始。我想需要注意的是,您的
knexfile.js
需要指定一个与用户的连接,该用户具有足够的资格来创建和删除数据库(因此可能需要一个只知道localhost
的“管理员”连接),并且必须创建和维护模板。更多信息,请参阅。我认为这里的诀窍是使用一点knex.raw
:
await db.raw('TRUNCATE graphs, users RESTART IDENTITY CASCADE');
CASCADE
是因为您不希望外键约束妨碍,而RESTART IDENTITY
是因为默认的Postgres行为不是重置序列。看
当我们讨论一个相关主题时,请允许我介绍一些可能会让您的生活更轻松的东西:模板数据库!模板是Postgres可以用来从已知状态(通过复制)非常快速地重新创建数据库的数据库。这甚至比截断表还要快,而且它允许我们在测试时跳过所有恼人的外键
例如,您可以使用raw
执行以下操作:
DROP DATABASE testdb;
CREATE DATABASE testdb TEMPLATE testdb_template;
这是一个非常便宜的操作,非常适合测试,因为每次运行测试时都可以从已知状态(不一定是空状态)开始。我想需要注意的是,您的knexfile.js
需要指定一个与用户的连接,该用户具有足够的资格来创建和删除数据库(因此可能需要一个只知道localhost
的“管理员”连接),并且必须创建和维护模板。更多信息,请参阅