express - 使用 mocha、chai、chai-http 和 sinon 在 Express API 上测试 try-catch
问题描述
我有一个使用 Express 创建的 API 应用程序,在控制器上具有此功能
/** UserController.ts */
--------------------------
public static get = async (req: Request, res: Response): Promise<void> => {
try {
const user = await UserModel.findById(<<id>>)
if (user) {
res.status(200).json(<I200Response>{ msg: 'user data', data: user })
}
} catch (e) {
res.status(500).json(<I500Response>{ error: e.message })
}
}
我正在尝试使用 sinon 测试“catch block”的工作,但我不明白。这是我尝试的数百个测试之一:
/** User.specs.ts */
---------------------
it('Internal server error', async () => {
const stubReq = chai.request(BASE)
const stub = sinon.stub(stubReq, 'get').throws(new Error('stub: Internal server error'))
const r = await request.get(API.info).set('Authorization', userToken)
stub.reset()
expect(r).to.have.status(500)
return expect(r.body).to.have.property('error').that.is.equal('stub: Internal server error')
})
但是响应的状态为 200 并获取所需的数据。
任何想法?
解决方案
您应该UserModel.findById
使用sinon.js
.
例如
UserController.ts
:
import { Request, Response } from 'express';
import { UserModel } from './UserModel';
type I500Response = any;
type I200Response = any;
export class UserController {
public static get = async (req: Request, res: Response): Promise<void> => {
try {
const user = await UserModel.findById(1);
if (user) {
res.status(200).json(<I200Response>{ msg: 'user data', data: user });
}
} catch (e) {
res.status(500).json(<I500Response>{ error: e.message });
}
};
}
UserModel.ts
:
export class UserModel {
public static findById(id: number) {
return { id, name: 'real username' };
}
}
app.ts
:
import express from 'express';
import { UserController } from './UserController';
const app = express();
const port = 3000;
app.get('/user/:id', UserController.get);
export { app };
app.test.ts
:
import chai, { expect } from 'chai';
import chaiHttp from 'chai-http';
import { app } from './app';
import { UserModel } from './UserModel';
import sinon from 'sinon';
chai.use(chaiHttp);
describe('62502383', () => {
it('should pass', (done) => {
const mError = new Error('stub: Internal server error');
const findByIdStub = sinon.stub(UserModel, 'findById').rejects(mError);
chai
.request(app)
.get('/user/1')
.end((err, res) => {
sinon.assert.calledWith(findByIdStub, 1);
expect(res).to.have.status(500);
expect(err).to.be.null;
expect(res.body.error).to.be.equal('stub: Internal server error');
done();
});
});
});
集成测试结果:
62502383
✓ should pass
1 passing (31ms)
-------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-------------------|---------|----------|---------|---------|-------------------
All files | 82.35 | 0 | 66.67 | 81.25 |
UserController.ts | 77.78 | 0 | 100 | 75 | 12-13
UserModel.ts | 50 | 100 | 0 | 50 | 3
app.ts | 100 | 100 | 100 | 100 |
-------------------|---------|----------|---------|---------|-------------------
推荐阅读
- laravel - 按 created_at 和文件关系分组集合
- node.js - 在 AngularJS 中定义自定义 Parsley 验证时遇到问题
- bots - “在控制室运行机器人运行器会话”选项的用途是什么?
- nhibernate - 如何在 NHibernate Criteria Query 中截断浮点值?
- java - 将十进制压缩为不区分大小写的字符串的推荐方法是什么?
- c++ - 如何在 gtest 中修复错误“ld: symbol(s) not found for architecture x86_64”
- r - 删除 ggplot 条形图中的空轮廓
- java - Spring Data Mongo:按数组交集查找
- c# - 从 ajax 检索数据时如何填充级联下拉列表?
- unity3d - 如何检测android设备是否真的需要读取权限才能访问Unity中的obb?