如何在node.js + Express.js + mongodb应用程序上asynchronous启动摩卡testing

问题似乎很微不足道,所以我真的很尴尬,我不能自己解决它,但我做了很多search谷歌和stackoverflow,没有任何帮助我呢。 我正在用node.js开发RESTful服务器,我想testing它的API。 服务器asynchronous初始化(它需要连接到数据库,从另一台服务器等请求令牌)。 所以我的server.js文件中的代码如下所示:

var express = require('express'); var app = express(); var bodyParser = require('body-parser'); var MongoClient = require('mongodb').MongoClient; var bunyan = require('bunyan'); // logger var routes = require('./routes/folrouter.js'); var TokenGetter = require('./utils/tokengetter'); MongoClient.connect('mongodb://localhost:27017/fol', function (err, db) { if (err) throw err; global.db = db; global.log = bunyan.createLogger({ name : "folserver", src : true, serializers: bunyan.stdSerializers, streams : [ { path : 'folserver.log', type : 'file' } ] }); global.log.info("folserver starts..."); var tg = new TokenGetter(); tg.on("token_received", function(token){ global.access_token = token; global.log.info("access_token received: " + token); //TO DO: compression and cache static content app.use(express.static(__dirname + '/public')); app.use(bodyParser.urlencoded({ extended: true } )); app.use(bodyParser.json()); app.use('/api', routes); app.listen(8080); console.log('Express server listening on port 8080'); }); tg.getToken(); }); //only for tests!!! module.exports = app; 

我在我的package.json文件中定义了脚本动作,所以我可以使用“npm test”命令从命令行运行testing:

 { "name": "folserver", "version": "0.0.0", "description": "Server side for my app", "main": "server.js", "dependencies": { ... }, "devDependencies": { "mocha": "^2.0.1", "should": "^4.3.0", "supertest": "^0.15.0" }, "scripts": { "test": "./node_modules/.bin/mocha --require should --reporter spec --ui bdd tests/tests.js", "start": "server.js" }, "repository": "", "author": "PainKiller", "private": true } 

然后我有以下代码tests.js:

 var should = require('should'); var request = require('supertest'); var app = require('../server.js'); describe("user.js", function () { describe("#upsert()", function () { it("should insert new user object correctly", function () { before(function (done) { console.log("before"); request(app) .post('api/user/upsert', user) .set('Accept', 'application/json') .end(function (error, res) { done(); }); }); after(function (done) { //after console.log("after"); done(); }); }); it("should update new user object correctly", function () { //Test Goes Here }); }); describe("#isregistered()", function () { it("should return false on id not in db", function () { //Test Goes Here }); it("should return true on id in db", function () { //Test Goes Here }); }); }); 

第一个问题 – 我的应用程序在testing开始后完全初始化 – 当我开始“npmtesting”时,从应用程序的console.log输出中看到它。 我看到我的testing通过控制台(他们什么都没有做,除了第一,但它也通过了)第二 – 我从来没有看到我的testingconsole.log输出 – 这真的让我很难过,可能是这个代码永远不会运行? 但如果这是真的,我怎么能看到我的testing在控制台的结果?

我看到了两种解决方法。 首先 – 在开始testing之前做延迟,我尝试过 – 用摩卡的超时命令 – 这没有帮助。 直到现在,我找不到一个合适的,不错的方法来停止执行一段时间的JS代码。 其次 – 使用应用程序发出事件,并开始对该事件进行testing,但是我也以这种方式失败。 也许我错了别的东西,我只是没有看到它,所以我感谢任何帮助和意见。 提前致谢!

用callback参数调用testing函数。 摩卡将然后asynchronous运行此function 。

编辑:只需重新组织你的案件中的钩子。

 describe("#upsert()", function () { var result; before(function (done) { console.log("before"); request(app) .post('api/user/upsert', user) .set('Accept', 'application/json') .end(function (error, res) { result = res; done(); }); }); after(function (done) { //after console.log("after"); done(); }); it("should insert new user object correctly", function () { // assert "result" object here }); it("should update new user object correctly", function () { //Test Goes Here }); }); 

因为在非asynchronous函数中有“before()”。 它()会退出而不是等待before()完成。 将asynchronous准备函数放置在外部或将其作为asynchronous函数本身调用()。

所以我终于在testing前初始化我的应用程序时遇到了问题。 这是最终的代码:

 var should = require('should'); var request = require('supertest'); var app = require('../server.js'); //this is root level hook with setTimeout do the trick before(function (done) { console.log("before all"); this.timeout(9000); setTimeout(done, 5000); }); describe("user.js", function () { describe("#upsert()", function () { before(function (done) { console.log("before 2"); this.timeout(5000); var user = { test: "test" } request(app) .post('/api/user/upsert') .set('Content-Length', JSON.stringify(user).length) .set('Accept', 'application/json') .send(user) .end(function (error, res) { if (error) throw error; console.log(res); done(); }); //done(); }); it("should insert new user object correctly", function (done) { console.log("it"); //console.log(app); //console.log(global.db); done(); }); after(function (done) { console.log("after"); done(); }); it("should update new user object correctly", function (done) { //Test Goes Here done(); }); }); describe("#isregistered()", function (done) { it("should return false on id not in db", function (done) { //Test Goes Here done(); }); it("should return true on id in db", function (done) { //Test Goes Here done(); }); }); }); 

一切工作asynchronous,我看到所有console.logs在正确的地方。