[英]how to start mocha tests asynchronously on node.js + Express.js + mongodb app
问题似乎非常琐碎,所以我很arra愧自己无法自行解决,但我在Google和stackoverflow上进行了大量搜索,但没有任何帮助。 我正在使用node.js开发RESTful服务器,我想测试它的API。 服务器异步初始化(它需要连接到db,从另一个服务器请求令牌等)。 因此,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”命令从命令行运行测试:
{
"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
});
});
});
第一个问题-测试开始后,我的应用程序完全初始化-当我开始“ npm测试”时,我从应用程序的console.log输出中看到了它。 而且我看到我的测试在控制台中通过了(除了第一点,它们什么都不做,但是也通过了)第二点-我从没在控制台中看到我的测试的console.log输出,这真的让我感到惊讶,可能这段代码永远不会运行吗? 但是,如果这是真的,我如何在控制台中查看测试结果?
我看到两种解决方法。 首先-在开始测试之前要延迟一些时间,我已经尝试过将--timeout命令与mocha配合使用-它没有帮助。 到现在为止,我找不到一段时间停止JS代码执行的合适方法。 其次–发出与应用程序相关的事件,并对该事件进行测试,但是我还是以这种方式失败了。 也许我在其他方面有问题,只是没看到,所以我感谢任何帮助和评论。 提前致谢!
使用回调参数调用测试函数。 然后,Mocha将异步运行此功能 。
编辑:只是在您的情况下重新组织您的钩子。
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
});
});
因为您在非异步函数中具有“ before()”。 it()将退出,而无需等待before()完成。 将异步准备函数放在外部或将其本身作为异步函数调用。
因此,我终于解决了在测试之前初始化我的应用程序的问题。 这是最终代码:
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();
});
});
});
一切都异步进行,我在正确的位置看到了所有console.logs。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.