2016-01-22 54 views
0

我有一个使用yoman全栈生成器生成的node/express js应用程序。我换了mongo/mongoose for cloudant db(这只是couchdb版本的付费版本)。我为Cloudant node.js库编写了一个包装器,该库用我的实例通过包装在承诺中的init()方法处理Cookie身份验证。我已经重构我的应用程序无法启动Express服务器,直到该数据库的连接已被确立为每个片段下面从我app.js防止supertest运行,直到快速服务器启动

myDb.init(config).then(function (db) { 
    logger.write(1001, '','Connection to Cloudant Established'); 
    // Start server 
    server.listen(config.port, config.ip, function() { 
    logger.write(1001, "",'Express server listening on '+config.port+', in '+app.get('env')+' mode'); 
    }); 
}); 

采取在我的表达路线我已经介绍了新的中间件,其重视的db对象到如下所示的跨中间件链的使用请求。在设置要使用的两个集合之前,这会获取数据库连接对象。

exports.beforeAll = function (req, res, next) { 
    req.my = {}; 

    // Adding my-db 
    req.my.db = {}; 
    req.my.db.connection = myDb.getDbConnection(); 
    req.my.db.orders = req.my.db.connection.use(dbOrders); 
    req.my.db.dbRefData = req.my.db.connection.use(dbRefData); 
    next(); 
}; 

这种机制,当我通过手动驾驶邮递员我的API作为Express服务器将无法启动,直到从DB连接的承诺后,已经得到解决。然而,当运行我的自动化测试时,前几个测试现在总是失败,因为在jasmine开始运行针对API的测试之前,应用程序尚未使用db完成初始化。我可以在我的日志中看到即将到来的请求以及返回undefined的中间件中的myDb.getDbConnection();。我正在使用supertest和node-jasmine来运行我的测试。例如

'use strict'; 

var app = require('../../app'); 
var request = require('supertest'); 

describe('GET /api/content', function() { 

    it('should respond with JSON object', function (done) { 
    request(app) 
     .get('/api/content') 
     .expect(200) 
     .expect('Content-Type', /json/) 
     .end(function (err, res) { 
     if (err) return done(err); 
     expect(res.body).toEqual(jasmine.any(Object)); 
     done(); 
     }); 
    }); 
}); 

所以,我的问题是如何防止supertest从直到server.listen()一步已经完成的myDb.init()调用的结果被解析发出请求?或者也许有一种茉莉花之前,我可以用它来阻止它运行的描述,直到承诺已解决?

回答

0

你可以让你app返回一个EventEmitter,它在完成初始化后发出一个“ready”事件。

然后,您的测试代码,在before子句中,可以等待“应用程序”事件从应用程序到达,然后再继续测试。

+0

谢谢格林 - 这工作得很好。对于任何在将来寻找这个答案的人来说,勾选ExpressJS事件发射器比节点更容易! – springdo