gpt4 book ai didi

Node.js Mocha Sequelize Error 连接管理器关闭后调用ConnectionManager.getConnection

转载 作者:搜寻专家 更新时间:2023-10-31 23:01:22 26 4
gpt4 key购买 nike

有2个mocha测试文件:

  1. 创建一个服务器并使用 chai 对其进行 ping 以检查它是否正常
    工作
  2. 创建服务器并测试用户插入数据库(sequelize postgres)

这两个服务器都初始化一个数据库连接。

当独立运行时,它们都通过了,当一起运行时,第二个失败并出现以下错误:

连接管理器关闭后调用错误ConnectionManager.getConnection

查看控制台,每次测试都会建立 2 次与数据库的连接,但仍充当单个池。

# db/index.js

global.TABLE_USERS = 'users';

const Promise = require('bluebird');
const Sequelize = require('sequelize');
const config = require('./../config');
const User = require('./User');

/**
* @return {Promise}
*/
const connect = () => {
return new Promise((resolve, reject) => {
let sequelize = new Sequelize(config.postgres.database, config.postgres.user, config.postgres.password, {
host: config.postgres.host,
dialect: 'postgres',
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
define: {
underscored: false,
freezeTableName: false,
charset: 'utf8',
dialectOptions: {
collate: 'utf8_general_ci'
}
},
});

let user = User(sequelize);

sequelize
.authenticate()
.then(() => {
resolve({
User: user,
sequelize: sequelize
})
})
.catch(err => {
console.error('Couldn\'t authenticate');
reject(err)
})
});
};

module.exports.connect = connect;

主服务器模块:

const express = require('express');
const bodyParser = require('body-parser');
global.Promise = require('bluebird');
let routing = require('./routing');
const config = require('./config');
const middleware = require('./middleware');
let database = require('./db');
let Repositories = require('./repositories');
let Services = require('./services');
let Controllers = require('./controllers');
const Promise = require('bluebird');

/**
* @property {http.Server} this.app
*/
class Server {

constructor() {
this.app = express();
}

/**
* @param {Function} beforeHook
*
*/
init(beforeHook = null) {
return this._initDatabaseConnection()
.then(() => {
this._initContainer(beforeHook);
this._initRoutes();
return this._initServer()
});
}

/**
*
* @param {Function} beforeHook
* @private
*/
_initContainer(beforeHook) {
this.container = {};
// Modify for testing before starting
if (typeof beforeHook === 'function') beforeHook(this);
this.container = Repositories(this.database);
this.container = Services(this.container);
this.controllers = Controllers(this.container);
}

/**
*
* @private
*/
_initRoutes() {
this.app.use(bodyParser.json());
middleware.handleCors(this.app);
this.app.use(routing({...this.controllers, ...this.services}));
middleware.handleErrors(this.app);
}

/**
*
* @private
*
* @return {Promise}
*/
_initServer() {
return new Promise((resolve, reject) => {
this.server = this.app.listen(config.app.port, () => {
console.log(`Server started listening in ${config.app.env} on port ${config.app.port}`);
resolve(this)
});
});
}

/**
*
* @return {Promise}
* @private
*/
_initDatabaseConnection() {
return database.connect()
.then(connection => {
this.database = connection;
console.log('Connected to the database');

return Promise.resolve()
})
}

/**
* @return {Promise}
*/
close() {
this.server.close();
return this.database.sequelize.close();
}
}

module.exports = Server;

第一个测试用例

const assert = require('assert');
const chai = require('chai'),
expect = chai.expect,
chaiHttp = require('chai-http');

chai.use(chaiHttp);

const Server = require('../../src/Server');

describe('Server app test', () => {

let server;

before(async () => {
server = await (new Server()).init();
});

after(async () => {
await server.close();
});

it('should say respond it\'s name', async () => {
let pingServer = () => {
return new Promise((resolve, reject) => {
chai.request(server.server)
.get('/')
.end((err, res) => {
expect(err).to.be.null;
expect(res).to.have.status(200);
resolve(res.body)
});
});
};

let res = await pingServer();
assert.equal(res.msg, 'API server');
});
});

第二个测试用例,UserControllerTest

const assert = require('assert');
const chai = require('chai'),
expect = chai.expect,
chaiHttp = require('chai-http');

chai.use(chaiHttp);

const sinon = require('sinon');
const Promise = require('bluebird');
const Response = require('./../../src/lib/RequestHelper');
const UserValidation = require('./../../src/validation/UserValidation');
const Server = require('./../../src/Server');
const ReCaptchaService = require('./../../src/services/ReCaptchaService');
const ValidationError = require('./../../src/errors/ValidationError');


describe('/users/signup', () => {

describe('valid reCaptcha scenario', () => {
let server, reCaptchaServiceStub;

before(async () => {
reCaptchaServiceStub = sinon.stub(ReCaptchaService.prototype, 'authenticate').returns(true);

function setReCaptchaServiceStub(server) {
server.services = {ReCaptchaService: new reCaptchaServiceStub()};
}

server = await (new Server()).init(setReCaptchaServiceStub);
});

after(async () => {
reCaptchaServiceStub.restore();
await server.database.User.destroy({where: {}});
await server.close();
});

beforeEach(async () => {
await server.database.User.destroy({where: {}});
});

it('should allow user to register', async () => {

let data = {email: 'myemail@gmail.com', password: '1234'};
data[UserValidation.CAPTCHA_RESPONSE] = 'captcha_token';

let signUp = (data) => {
return new Promise((resolve, reject) => {
chai.request(server.server)
.post('/users/signup')
.send(data)
.end((err, res) => {
console.log(res.body)
expect(err).to.be.null;
expect(res).to.have.status(Response.STATUS_OK);
resolve(res.body)
});
});
};

let res = await signUp(data);
expect(res.token).to.be.a('string');
});
});

describe('invalid reCaptcha scenario', () => {
let server, reCaptchaServiceStub;

before(async () => {
reCaptchaServiceStub = sinon.stub(ReCaptchaService.prototype, 'authenticate')
.onCall()
.throws(new ValidationError('some err'));

function setReCaptchaServiceStub(server) {
server.container.ReCaptchaService = new reCaptchaServiceStub()
}

server = await (new Server()).init(setReCaptchaServiceStub);
});

after(async () => {
reCaptchaServiceStub.restore();
await server.close();
});

beforeEach(async () => {
await server.database.User.destroy({where: {}});
});

it('should send a bad request on invalid reCaptcha', async () => {

let data = {email: 'myemail@gmail.com', password: '1234'};
data[UserValidation.CAPTCHA_RESPONSE] = 'random_token';

let signUp = (data) => {
return new Promise((resolve, reject) => {
chai.request(server.server)
.post('/users/signup')
.send(data)
.end((err, res) => {
expect(err).to.not.be.null;
expect(res).to.have.status(Response.STATUS_BAD_REQUEST);
resolve(res.body);
});
});
};

let res = await signUp(data);
expect(res.err).to.equal(UserValidation.ERR_INVALID_RECAPTCHA);
});
});
});

最佳答案

对此进行更多研究后,这是导致问题的以下行为。

当运行 mocha 以递归方式测试文件时,它作为单个进程运行,这会在关闭与 sequelize 的连接时导致冲突。

为避免此问题,您不应使用 sequelize 关闭连接,而应使用 mocha --exit 设置一个额外选项,以终止事件循环中的任何其他循环测试完成后,自动关闭sequelize连接。

关于Node.js Mocha Sequelize Error 连接管理器关闭后调用ConnectionManager.getConnection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47970050/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com