首页 > 解决方案 > 如何为 chai-http 导出 node express 应用程序

问题描述

我有一个带有几个端点的快速应用程序,目前正在使用 mocha、chai 和 chai-http 对其进行测试。在我为池化 mongo 连接添加逻辑并开始构建依赖于数据库连接的端点之前,这一切正常。基本上,在我导入我的 API 路由并启动应用程序之前,我想确保我已连接到 mongo。

我的问题是我无法理解如何为 chai-http 导出我的应用程序,但还要确保在测试任何端点之前存在数据库连接。

在这里,我连接到 mongo,然后在回调中应用我的 API 并启动应用程序。这个例子的问题是我的测试将在连接到数据库之前开始,并且在定义任何端点之前。我可以移动app.listen到回调api(app)之外MongoPool.connect(),但是当测试运行时我仍然遇到没有数据库连接的问题,所以我的端点会失败。

服务器.js

import express from 'express';
import api from './api';
import MongoPool from './lib/MongoPool';
let app = express();
let port = process.env.PORT || 3000;
MongoPool.connect((err, success) => {
    if (err) throw err;
    if (success) {
        console.log("Connected to db.")
        // apply express router endpoints to app
        api(app);
        app.listen(port, () => {
            console.log(`App listening on port ${port}`);
        })
    } else {
        throw "Couldnt connect to db";
    }

})
export default app;

如何使用 chai-http 测试我的端点,同时确保在实际执行测试之前存在池连接?以符合我正在使用的测试的方式编写我的应用程序感觉很脏。这是我的池实现的设计问题吗?有没有更好的方法来使用 chai-http 测试我的端点?

这是我正在运行的测试

测试.js

let chai = require('chai');
let chaiHttp = require('chai-http');
let server = require('../server').default;;
let should = chai.should();


chai.use(chaiHttp);
//Our parent block
describe('Forecast', () => {
/*
  * Test the /GET route
  */
  describe('/GET forecast', () => {
      it('it should GET the forecast', (done) => {
        chai.request(server)
            .get('/api/forecast?type=grid&lat=39.2667&long=-81.5615')
            .end((err, res) => {
                res.should.have.status(200);
              done();
            });
      });
  });

});

这是我正在测试的端点

/api/forecast.js

import express from 'express';
import MongoPool from '../lib/MongoPool';
let router = express.Router();
let db = MongoPool.db();

router.get('/forecast', (req, res) => {
    // do something with DB here
})

export default router;

感谢您的任何帮助

标签: javascriptnode.jsmongodbexpresschai

解决方案


在收到一些好的反馈后,我发现这个解决方案最适合我,基于Gomzy 的回答Vikash Singh 的回答

server.js中,我连接到 mongo 池,然后在 express 上发出 'ready' 事件app。然后在测试中,我可以before()用来等待在应用程序上发出“就绪”事件。一旦发生这种情况,我就可以开始执行测试了。

服务器.js

import express from 'express';
import bodyParser from 'body-parser';
import MongoPool from './lib/MongoPool';
let app = express();
let port = process.env.PORT || 5000;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

(async () => {
    await MongoPool.connect();
    console.log("Connected to db.");
    require('./api').default(app);
    app.listen(port, () => {
        console.log(`Listening on port ${port}.`)
        app.emit("ready");
    });
})();

export default app;

测试.js

//Require the dev-dependencies
import chai from 'chai';
import chaiHttp from 'chai-http';
import server from '../src/server'; 
let should = chai.should();
chai.use(chaiHttp);

before(done => {
  server.on("ready", () => {
    done();
  })
})
describe('Forecast', () => {
  describe('/GET forecast', () => {
    it('it should GET the forecast', (done) => {
      chai.request(server)
          .get('/api/forecast?type=grid&lat=39.2667&long=-81.5615')
          .end((err, res) => {
              res.should.have.status(200);
            done();
          });
    });
  });

});

推荐阅读