2016-01-22 53 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