Mocha用Knex测试PostgreSQL给我一个MigrationLocked错误 [英] Mocha testing PostgreSQL with Knex is giving me a MigrationLocked error
问题描述
在某种程度上,我可以使用Node/PostgreSQL/Knex开发本地开发环境,因为我可以使用API将其发布到机器上的开发数据库中.我现在正在尝试为此功能创建测试,但出现错误.
I have got a local development environment working for Node/PostgreSQL/Knex in the sense that I can post to a development database on my machine using an API. I am now trying to create tests for this functionality but am getting an error.
这是我的配置:
//knexfile.js
module.exports = {
development: {
client: 'pg',
connection: {
host: '127.0.0.1',
user: 'dbUser',
password: 'dbpword',
port: 5432,
database: 'example-name'
},
migrations: {
directory: __dirname + '/db/migrations'
},
seeds: {
directory: __dirname + '/db/seeds/development'
}
},
}
//db.js
const config = require('../knexfile.js');
const env = process.env.NODE_ENV || 'development';
const knex = require("knex")(config[env]);
module.exports = knex;
knex.migrate.latest([config]);
然后是我的测试:
import chai from 'chai';
import { expect } from 'chai';
import chaiHttp from 'chai-http';
import knex from '../../db/db';
import app from '../../server';
chai.use(chaiHttp);
describe('Tokens API', () => {
beforeEach((done) => {
knex.migrate.rollback()
.then(() => {
knex.migrate.latest()
.then(() => {
return knex.seed.run()
.then(() => {
done();
});
});
});
});
afterEach((done) => {
knex.migrate.rollback()
.then(() => {
done();
});
});
describe('POST /users', () => {
it('posts a list of users to the database with all mandatory fields', (done) => {
chai.request(app)
.post('/users')
.send({
"users": [
"steve",
"whoever",
"matt",
"another"]})
.end((err, res) => {
expect(err).to.be.null;
expect(res).to.have.status(200);
expect(res).to.be.json;
done();
});
});
});
});
运行此命令时,两次出现以下错误-我认为对于beforeEach块中的knex调用:
When I run this I get the following error twice - I think for the knex calls in the beforeEach block:
Knex:warning - Can't take lock to run migrations: Migration table is already locked
Knex:warning - If you are sure migrations are not running you can release the lock manually by deleting all the rows from migrations lock table: knex_migrations_lock
Unhandled rejection MigrationLocked: Migration table is already locked
我尝试了很多事情-包括清除knex_migrations_lock表.我在网上可以找到的唯一支持是此线程,该线程建议使用以下方法清除锁表DELETE FROM Migrations_lock where id <> 0;
,但是我的锁表只有一个is_locked
列,其值为零.
I have tried numerous things - including clearing out the knex_migrations_lock table. The only support I can find online is this thread, which suggests clearing out the lock table using DELETE FROM Migrations_lock where id <> 0;
, however my lock table only has a is_locked
column with zero values.
知道发生了什么事吗?
我刚刚意识到,如果您删除所有的knex调用,则测试实际上会通过.可能是因为我实际上两次调用过knex-一次是从db.js
调用,一次是间接地通过server.js
调用吗?如果是这样,我该如何避免这样做-因为我确实需要调用Node的knex设置才能运行它?
I've just realised if you edit out all the knex calls, the test actually passes. Could this be because I am effectively calling knex twice - once from db.js
and once indirectly through server.js
? If that's the case, how do I avoid doing this - because surely I need to call the knex setup for Node to run it?
推荐答案
对于绊脚石的人来说,问题实际上出在db.js
上,尤其是最后一行:
For anyone stumbling across this, the problem was actually coming from db.js
, specifically the last line:
const config = require('../knexfile.js');
const env = process.env.NODE_ENV || 'development';
const knex = require("knex")(config[env]);
module.exports = knex;
knex.migrate.latest([config]);
当然这是异步的,并且测试在尝试运行自己的knex函数之前会导入该文件,从而导致锁定.为了解决这个问题,我添加了一个子句来阻止它在测试时运行:
Of course this is asynchronous, and the tests were importing this file before trying to run their own knex functions, causing the lock. I got round this by adding a clause to block this running while testing:
if(process.env.NODE_ENV != 'test') {
knex.migrate.latest([config])
}
然后,您可以通过将process.env.NODE_ENV='test'
添加到每个规范文件或安装 npm env测试模块.
You can then create a test environment by adding process.env.NODE_ENV='test'
to each spec file, or by installing the npm env test module.
这篇关于Mocha用Knex测试PostgreSQL给我一个MigrationLocked错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!