Chai http - 双重回调问题
Chai http - double callback issue
我使用 chai-http 对我的 REST api 进行了正常的单元测试。它失败并出现以下错误
warn: double callback!
error: { SyntaxError: Unexpected token { in JSON at position 58
at Object.parse (native)
at IncomingMessage.<anonymous> (E:\projects\node_modules\chai-http\node_modules\superagent\lib\node\parsers\json.js:8:35)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)
rawResponse: '{"books":[],"count":0,"page":1,"pages":0,"pageSize":10}{"books":[],"count":0,"page":1,"pages":0,"pageSize":10}',
statusCode: 200,
response: undefined }
如您所见,rawResponse
是重复的,因此测试失败。我调试了代码,控制器代码只被调用一次,输出正确。但是无法理解为什么会出现这个错误。
以下是测试代码
// some code to mock mongoose with mockgoose
....
....
let server = require('../../../server');
let should = chai.should();
chai.use(chaiHttp);
describe.only('Books', () => {
describe('/GET book', () => {
it('it should GET all the books', (done) => {
chai.request(server)
.get('/api/books')
.end((err, res) => {
console.log(res);
res.should.have.status(200);
done();
}).catch(function(err){
console.error(err);
done(err);
});
});
});
});
您正在混合使用两种类型的异步处理:使用 .end/.catch
而不是 .then/.catch
或 .end
因为有错误,.end()
(第一个参数,err
,设置)和 .catch()
都被调用,导致 done
回调叫了两次。
这是一个使用 .then/.catch
的解决方案,结合 Mocha 的内置 promise 支持(不使用 done
):
it('it should GET all the books', () => {
return chai.request(server)
.get("/api/books")
.then(res => {
console.log(res);
res.should.have.status(200);
})
.catch(err => {
console.error(err);
throw err; // Re-throw the error if the test should fail when an error happens
});
});
并使用 .end
:
it('it should GET all the books', done => {
chai.request(server)
.get("/api/books")
.end((err, res) => {
if (err) return done(err);
console.log(res);
res.should.have.status(200);
done();
});
});
我使用 chai-http 对我的 REST api 进行了正常的单元测试。它失败并出现以下错误
warn: double callback!
error: { SyntaxError: Unexpected token { in JSON at position 58
at Object.parse (native)
at IncomingMessage.<anonymous> (E:\projects\node_modules\chai-http\node_modules\superagent\lib\node\parsers\json.js:8:35)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)
rawResponse: '{"books":[],"count":0,"page":1,"pages":0,"pageSize":10}{"books":[],"count":0,"page":1,"pages":0,"pageSize":10}',
statusCode: 200,
response: undefined }
如您所见,rawResponse
是重复的,因此测试失败。我调试了代码,控制器代码只被调用一次,输出正确。但是无法理解为什么会出现这个错误。
以下是测试代码
// some code to mock mongoose with mockgoose
....
....
let server = require('../../../server');
let should = chai.should();
chai.use(chaiHttp);
describe.only('Books', () => {
describe('/GET book', () => {
it('it should GET all the books', (done) => {
chai.request(server)
.get('/api/books')
.end((err, res) => {
console.log(res);
res.should.have.status(200);
done();
}).catch(function(err){
console.error(err);
done(err);
});
});
});
});
您正在混合使用两种类型的异步处理:使用 .end/.catch
而不是 .then/.catch
或 .end
因为有错误,.end()
(第一个参数,err
,设置)和 .catch()
都被调用,导致 done
回调叫了两次。
这是一个使用 .then/.catch
的解决方案,结合 Mocha 的内置 promise 支持(不使用 done
):
it('it should GET all the books', () => {
return chai.request(server)
.get("/api/books")
.then(res => {
console.log(res);
res.should.have.status(200);
})
.catch(err => {
console.error(err);
throw err; // Re-throw the error if the test should fail when an error happens
});
});
并使用 .end
:
it('it should GET all the books', done => {
chai.request(server)
.get("/api/books")
.end((err, res) => {
if (err) return done(err);
console.log(res);
res.should.have.status(200);
done();
});
});