Mocha testing PostgreSQL with Knex is giving me a MigrationLocked error

三世轮回 提交于 2019-12-04 14:54:25

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]);

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])
}

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.

Had the exact same issue, ended up being due to my API calling the database when being initialized by the supertest library.

For example, my test file:

var db = require('../db');
var api = require('../api');

var supertest = require('supertest')(api);

describe('Session routes', () => {
  beforeEach((done) => {
    db.migrate.rollback()
      .then(() => {
        db.migrate.latest()
          .then(() => {
            return db.seed.run()
              .then(() => {
                done();
              });
          });
      });
  });

  afterEach((done) => {
    db.migrate.rollback()
      .then(() => {
        done();
      });
  });

  it('GET /session should error with no token', (done) => {
    supertest
      .get('/session')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(401, {
        error: 'Unauthorized'
      }, done);
  });
});

On line 2, it requires my api - when my api is required the following code gets run straight away to initialize my api's external services API:

var db = require('./other-postgres-library');
var servicesApi = require('./services/api')(db);

This would connect to a bunch of external services and write the results to the database.

So when tests were running my APP was throwing errors because it was trying to write to a database which was being rolled back/migrated/seeded etc.

I changed my inner services API to initialize lazily and all my problems have disappeared.

In your case, I would hazard to guess when your tests runs this line import app from '../../server'; your app/server code is trying to running some queries against the database.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!