我有一个使用 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 的"捕获块"作品,但我不明白。这是我尝试过的数百个测试之一:
/** 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 并获取所需的数据。
知道吗?
您应该使用sinon.js
将方法存根UserModel.findById
并带有被拒绝的承诺。
例如
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 |
-------------------|---------|----------|---------|---------|-------------------