测试代码
var utils = require('./utils');
var request = require('supertest');
var should = require('should');
var app = require('../app');
describe('addition', function () {
//... previous test
it('should return 2 given the url /add/1/1', function (done) {
request(app)
.get('/add/1/1')
.expect(200)
.end(function (err, res) {
should.not.exist(err);
parseFloat(res.text).should.equal(2);
done();
});
});
});
app.js 中需要测的路由
app.get('/add/:first/:second', function (req, res) {
var sum = parseFloat(req.params.first) + parseFloat(req.params.second);
res.send(200, String(sum));
});
上述测试会出现报错
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
但是我有在 .end 中调用done()
后来我把代码改为(去掉了done)
describe('addition', function () {
//... previous test
it('should return 2 given the url /add/1/1', function () {
request(app)
.get('/add/1/1')
.expect(200)
.end(function (err, res) {
should.not.exist(err);
parseFloat(res.text).should.equal(2);
});
});
});
反而没有报错,测试通过了.........
✓ should return 2 given the url /add/1/1
我不明白这其中的道理......
理论上讲,是需要有done 去提醒mocha 异步已经完成了。
mocha官网的描述与例子
Testing asynchronous code with Mocha could not be simpler! Simply invoke the callback when your test is complete. By adding a callback (usually named done) to it() Mocha will know that it should wait for completion.
describe('User', function() {
describe('#save()', function() {
it('should save without error', function(done) {
var user = new User('Luna');
user.save(function(err) {
if (err) throw err;
done();
});
});
});
});
supertest上的例子
describe('GET /users', function() {
it('respond with json', function(done) {
request(app)
.get('/users')
.set('Accept', 'application/json')
.expect(200)
.end(function(err, res) {
if (err) return done(err);
done();
});
});
});
都需要调done, 但是我一调用done 就报错了,不调用done反而是好的。
不加 done 时,测试用例是同步的。这个时候异步回调里的断言不会执行,测试用例就过了。推测 app 里的代码有问题,请求超时了。