在 Node + Express 应用程序中使用 Mocha 和 Chai 测试 try catch
Test try catch with Mocha and Chai in Node + Express appp
我的 nodeJS 应用程序具有如下简单的路由:
const express = require('express')
const router = express.Router();
const logger = require('../logger');
router.use('/logMessage',(req, res) => {
try {
logger.info(req.query.message);
res.send({
statusMessage: 'success'
})
} catch (err) {
logger.error('error in logging');
logger.error(err);
res.send({
statusMessage: 'failure'
})
}
});
module.exports = router;
我可以使用下面的代码成功测试 try 块,但是如何测试 catch 块?
测试 try 块:
describe('GET /logMessage', () => {
it('should host logger api', (done) => {
chai.request(server)
.get('/logMessage?message=testMessage')
.end((err, response) => {
response.should.have.status(200);
done();
});
});
});
你需要让try块中的语句抛出错误。您可以使用 sinonjs 来实现。这里为了演示,我会重写console.info
的实现,当消息为"makeError"
时,抛出错误
例如
router.js
:
const express = require('express');
const router = express.Router();
const logger = console;
router.use('/logMessage', (req, res) => {
try {
logger.info(req.query.message);
res.send({
statusMessage: 'success',
});
} catch (err) {
logger.error('error in logging');
logger.error(err);
res.send({
statusMessage: 'failure',
});
}
});
module.exports = router;
server.js
:
const express = require('express');
const app = express();
const router = require('./router');
const port = 3000;
app.use(router);
if (require.main === module) {
app.listen(port, () => console.log('server is listening on port:' + port));
}
module.exports = app;
server.test.js
:
const server = require('./server');
const chai = require('chai');
const sinon = require('sinon');
const chaiHttp = require('chai-http');
chai.use(chaiHttp);
chai.should();
describe('62080151', () => {
describe('GET /logMessage', () => {
it('should host logger api', (done) => {
chai
.request(server)
.get('/logMessage?message=testMessage')
.end((err, response) => {
response.should.have.status(200);
done();
});
});
it('should handle error', (done) => {
sinon.stub(console, 'info').callsFake((message) => {
if (message === 'makeError') {
throw new Error('custom error');
}
});
sinon.spy(console, 'error');
chai
.request(server)
.get('/logMessage?message=makeError')
.end((err, response) => {
response.should.have.status(200);
sinon.assert.match(console.error.firstCall.calledWithExactly('error in logging'), true);
console.error.secondCall.args[0].should.be.instanceOf(Error);
done();
});
});
});
});
集成测试结果与覆盖率报告:
62080151
GET /logMessage
testMessage
✓ should host logger api
error in logging
Error: custom error
at Console.sinon.stub.callsFake (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/62080151/server.test.js:23:17)
at Object.invoke (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/sinon/lib/sinon/behavior.js:163:32)
at Console.functionStub (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/sinon/lib/sinon/stub.js:39:43)
at Function.invoke (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/sinon/lib/sinon/proxy-invoke.js:47:47)
at Console.bound consoleCall [as info] (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/sinon/lib/sinon/proxy.js:214:26)
at router.use (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/62080151/router.js:1:1894)
at Layer.handle [as handle_request] (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:317:13)
at /Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:335:12)
at next (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:174:3)
at router (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:47:12)
at Layer.handle [as handle_request] (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:317:13)
at /Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:335:12)
at next (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:275:10)
at expressInit (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/middleware/init.js:40:5)
at Layer.handle [as handle_request] (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:317:13)
at /Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:335:12)
at next (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:275:10)
at query (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/middleware/query.js:45:5)
at Layer.handle [as handle_request] (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:317:13)
at /Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:335:12)
at next (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:174:3)
at Function.handle (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/application.js:174:10)
at Server.app (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/express.js:39:9)
at Server.emit (events.js:198:13)
at parserOnIncoming (_http_server.js:677:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
✓ should handle error (43ms)
2 passing (81ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 90 | 50 | 50 | 94.74 |
router.js | 100 | 100 | 100 | 100 |
server.js | 77.78 | 50 | 0 | 87.5 | 9
-----------|---------|----------|---------|---------|-------------------
我的 nodeJS 应用程序具有如下简单的路由:
const express = require('express')
const router = express.Router();
const logger = require('../logger');
router.use('/logMessage',(req, res) => {
try {
logger.info(req.query.message);
res.send({
statusMessage: 'success'
})
} catch (err) {
logger.error('error in logging');
logger.error(err);
res.send({
statusMessage: 'failure'
})
}
});
module.exports = router;
我可以使用下面的代码成功测试 try 块,但是如何测试 catch 块?
测试 try 块:
describe('GET /logMessage', () => {
it('should host logger api', (done) => {
chai.request(server)
.get('/logMessage?message=testMessage')
.end((err, response) => {
response.should.have.status(200);
done();
});
});
});
你需要让try块中的语句抛出错误。您可以使用 sinonjs 来实现。这里为了演示,我会重写console.info
的实现,当消息为"makeError"
时,抛出错误
例如
router.js
:
const express = require('express');
const router = express.Router();
const logger = console;
router.use('/logMessage', (req, res) => {
try {
logger.info(req.query.message);
res.send({
statusMessage: 'success',
});
} catch (err) {
logger.error('error in logging');
logger.error(err);
res.send({
statusMessage: 'failure',
});
}
});
module.exports = router;
server.js
:
const express = require('express');
const app = express();
const router = require('./router');
const port = 3000;
app.use(router);
if (require.main === module) {
app.listen(port, () => console.log('server is listening on port:' + port));
}
module.exports = app;
server.test.js
:
const server = require('./server');
const chai = require('chai');
const sinon = require('sinon');
const chaiHttp = require('chai-http');
chai.use(chaiHttp);
chai.should();
describe('62080151', () => {
describe('GET /logMessage', () => {
it('should host logger api', (done) => {
chai
.request(server)
.get('/logMessage?message=testMessage')
.end((err, response) => {
response.should.have.status(200);
done();
});
});
it('should handle error', (done) => {
sinon.stub(console, 'info').callsFake((message) => {
if (message === 'makeError') {
throw new Error('custom error');
}
});
sinon.spy(console, 'error');
chai
.request(server)
.get('/logMessage?message=makeError')
.end((err, response) => {
response.should.have.status(200);
sinon.assert.match(console.error.firstCall.calledWithExactly('error in logging'), true);
console.error.secondCall.args[0].should.be.instanceOf(Error);
done();
});
});
});
});
集成测试结果与覆盖率报告:
62080151
GET /logMessage
testMessage
✓ should host logger api
error in logging
Error: custom error
at Console.sinon.stub.callsFake (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/62080151/server.test.js:23:17)
at Object.invoke (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/sinon/lib/sinon/behavior.js:163:32)
at Console.functionStub (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/sinon/lib/sinon/stub.js:39:43)
at Function.invoke (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/sinon/lib/sinon/proxy-invoke.js:47:47)
at Console.bound consoleCall [as info] (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/sinon/lib/sinon/proxy.js:214:26)
at router.use (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/src/Whosebug/62080151/router.js:1:1894)
at Layer.handle [as handle_request] (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:317:13)
at /Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:335:12)
at next (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:174:3)
at router (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:47:12)
at Layer.handle [as handle_request] (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:317:13)
at /Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:335:12)
at next (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:275:10)
at expressInit (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/middleware/init.js:40:5)
at Layer.handle [as handle_request] (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:317:13)
at /Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:335:12)
at next (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:275:10)
at query (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/middleware/query.js:45:5)
at Layer.handle [as handle_request] (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:317:13)
at /Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:335:12)
at next (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:275:10)
at Function.handle (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/router/index.js:174:3)
at Function.handle (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/application.js:174:10)
at Server.app (/Users/ldu020/workspace/github.com/mrdulin/expressjs-research/node_modules/express/lib/express.js:39:9)
at Server.emit (events.js:198:13)
at parserOnIncoming (_http_server.js:677:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
✓ should handle error (43ms)
2 passing (81ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 90 | 50 | 50 | 94.74 |
router.js | 100 | 100 | 100 | 100 |
server.js | 77.78 | 50 | 0 | 87.5 | 9
-----------|---------|----------|---------|---------|-------------------