mocha/chai.js 测试工具:https 调用在 after() 函数中不起作用
mocha/chai.js testing harness: https calls do not work from after() function
mocha.js: 3.4.2
chai.js: 4.1.0
node.js: 6.10.3
npm: 5.3.0
我已经为部署在 node.js 下的 RESTful 服务设置了一个简单的测试工具。测试工具依赖于 mocha.js / chai.js
。每个通过 https 调用端点的测试都有效。同样,before()
和 after()
函数被调用。但是:似乎不可能在 after()
函数中调用任何 RESTful 端点。为什么?
由于 after()
在测试结束时出现,我认为 RESTful 端点的异步调用根本没有时间 return 在测试过程退出之前。所以,我编写了一个忙等待循环来给响应一些时间。不行:端点调用在 after()
.
中根本不起作用
这是我的 package.json
:
{
"name": "so-mcv-example",
"version": "1.0.0",
"description": "Minimum, Complete, and Verifiable Example",
"main": "index.js",
"dependencies": {
"restify": "^4.3.0"
},
"engines": {
"node": "6.10.3",
"npm": "5.3.0"
},
"devDependencies": {
"chai": "^4.1.0",
"chai-http": "^3.0.0",
"mocha": "^3.4.2"
},
"scripts": {
"test": "mocha"
}
}
我的 index.js
看起来像这样:
const restify = require('restify'),
fs = require('fs');
const server = restify.createServer({
certificate: fs.readFileSync('security/server.crt'),
key: fs.readFileSync('security/server.key'),
name: 'so-mcv-example'
});
server.listen(443, function() {
console.log('%s listening at %s', server.name, server.url);
});
server.pre(restify.pre.userAgentConnection());
server.get('/status', function(req, res, next) {
res.send({ status: 'so-mcv-example is running ok.' });
return next();
});
在test
目录下,我有mocha.opts
:
--require ./test/test.bootstrap
和test.bootstrap.js
:
process.env.NODE_ENV = 'test';
// CAUTION: never do this in production! For testing purposes, we ignore
// faults in the standard SSL handshaking.
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
后面的设置协商 index.js
中使用的自签名 SSL 证书。在 test/status-test.js
中,我有:
const chai = require('chai');
const expect = chai.expect;
const should = chai.should();
const server = 'https://localhost';
chai.use(require('chai-http'));
before(function() {
if (process.env.NODE_ENV != "test") {
this.skip();
}
// XXX Wipe the database.
console.log("Wipe the database BEFORE tests.");
});
describe('GET /status', function() {
it('passes, as expected', function(done) {
chai.request(server)
.get('/status')
.end(function(err, res) {
expect(err).to.be.null;
expect(res).to.have.status(200);
done();
});
});
});
after(function() {
if (process.env.NODE_ENV != "test") {
this.skip();
}
chai.request(server)
.get('/status')
.end(function(err, res) {
expect(err).to.be.null;
expect(res).to.have.status(200);
console.log("2nd call to /status returned.");
done();
});
});
诚然,使用 chai
调用 after()
函数中的端点是人为设计的。那不是重点。关键是 console.log()
指令根本不会执行。即当我运行npm test
时,结果为:
> so-mcv-example@1.0.0 test /Users/charlie/workspace/so-mcv-mocha
> mocha
Wipe the database BEFORE tests.
GET /status
✓ passes, as expected (44ms)
1 passing (56ms)
请参阅下面我的回答,了解为什么 console.log()
没有被执行。
为了解决这个问题,我添加了选项 --no-exit
到 mocha.opts
:
--require ./test/test.bootstrap
--no-exit
然后当我运行npm test
时,输出想要的结果:
> so-mcv-example@1.0.0 test /Users/charlie/workspace/so-mcv-mocha
> mocha
Wipe the database BEFORE tests.
GET /status
✓ passes, as expected (43ms)
1 passing (55ms)
2nd call to /status returned.
我相信我已经找到了解决办法。在 after()
中,如果您在测试环境外部的服务上异步调用某个端点,则该异步调用会排队,不会立即执行。这就是node.js中调用异步函数的本质。好吧,如果在 after()
调用之后没有逻辑,那么 mocha
会立即通过调用 process.exit()
退出!最终结果是您对外部端点的异步调用保持排队状态并且从未被调用。
解决方案:在 test
目录下的 mocha.opts
中,只需安装选项 --no-exit
.
mocha.js: 3.4.2
chai.js: 4.1.0
node.js: 6.10.3
npm: 5.3.0
我已经为部署在 node.js 下的 RESTful 服务设置了一个简单的测试工具。测试工具依赖于 mocha.js / chai.js
。每个通过 https 调用端点的测试都有效。同样,before()
和 after()
函数被调用。但是:似乎不可能在 after()
函数中调用任何 RESTful 端点。为什么?
由于 after()
在测试结束时出现,我认为 RESTful 端点的异步调用根本没有时间 return 在测试过程退出之前。所以,我编写了一个忙等待循环来给响应一些时间。不行:端点调用在 after()
.
这是我的 package.json
:
{
"name": "so-mcv-example",
"version": "1.0.0",
"description": "Minimum, Complete, and Verifiable Example",
"main": "index.js",
"dependencies": {
"restify": "^4.3.0"
},
"engines": {
"node": "6.10.3",
"npm": "5.3.0"
},
"devDependencies": {
"chai": "^4.1.0",
"chai-http": "^3.0.0",
"mocha": "^3.4.2"
},
"scripts": {
"test": "mocha"
}
}
我的 index.js
看起来像这样:
const restify = require('restify'),
fs = require('fs');
const server = restify.createServer({
certificate: fs.readFileSync('security/server.crt'),
key: fs.readFileSync('security/server.key'),
name: 'so-mcv-example'
});
server.listen(443, function() {
console.log('%s listening at %s', server.name, server.url);
});
server.pre(restify.pre.userAgentConnection());
server.get('/status', function(req, res, next) {
res.send({ status: 'so-mcv-example is running ok.' });
return next();
});
在test
目录下,我有mocha.opts
:
--require ./test/test.bootstrap
和test.bootstrap.js
:
process.env.NODE_ENV = 'test';
// CAUTION: never do this in production! For testing purposes, we ignore
// faults in the standard SSL handshaking.
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
后面的设置协商 index.js
中使用的自签名 SSL 证书。在 test/status-test.js
中,我有:
const chai = require('chai');
const expect = chai.expect;
const should = chai.should();
const server = 'https://localhost';
chai.use(require('chai-http'));
before(function() {
if (process.env.NODE_ENV != "test") {
this.skip();
}
// XXX Wipe the database.
console.log("Wipe the database BEFORE tests.");
});
describe('GET /status', function() {
it('passes, as expected', function(done) {
chai.request(server)
.get('/status')
.end(function(err, res) {
expect(err).to.be.null;
expect(res).to.have.status(200);
done();
});
});
});
after(function() {
if (process.env.NODE_ENV != "test") {
this.skip();
}
chai.request(server)
.get('/status')
.end(function(err, res) {
expect(err).to.be.null;
expect(res).to.have.status(200);
console.log("2nd call to /status returned.");
done();
});
});
诚然,使用 chai
调用 after()
函数中的端点是人为设计的。那不是重点。关键是 console.log()
指令根本不会执行。即当我运行npm test
时,结果为:
> so-mcv-example@1.0.0 test /Users/charlie/workspace/so-mcv-mocha
> mocha
Wipe the database BEFORE tests.
GET /status
✓ passes, as expected (44ms)
1 passing (56ms)
请参阅下面我的回答,了解为什么 console.log()
没有被执行。
为了解决这个问题,我添加了选项 --no-exit
到 mocha.opts
:
--require ./test/test.bootstrap
--no-exit
然后当我运行npm test
时,输出想要的结果:
> so-mcv-example@1.0.0 test /Users/charlie/workspace/so-mcv-mocha
> mocha
Wipe the database BEFORE tests.
GET /status
✓ passes, as expected (43ms)
1 passing (55ms)
2nd call to /status returned.
我相信我已经找到了解决办法。在 after()
中,如果您在测试环境外部的服务上异步调用某个端点,则该异步调用会排队,不会立即执行。这就是node.js中调用异步函数的本质。好吧,如果在 after()
调用之后没有逻辑,那么 mocha
会立即通过调用 process.exit()
退出!最终结果是您对外部端点的异步调用保持排队状态并且从未被调用。
解决方案:在 test
目录下的 mocha.opts
中,只需安装选项 --no-exit
.