如何在typescript中使用sinon来存根表示中间件?
我正在尝试使用typescript、mocha、sinon和chai http为我的express路由器编写一个集成测试。这个路由器使用我编写的自定义中间件,它检查头中的JWT 理想情况下,我希望存根我的如何在typescript中使用sinon来存根表示中间件?,typescript,express,mocha.js,sinon,chai-http,Typescript,Express,Mocha.js,Sinon,Chai Http,我正在尝试使用typescript、mocha、sinon和chai http为我的express路由器编写一个集成测试。这个路由器使用我编写的自定义中间件,它检查头中的JWT 理想情况下,我希望存根我的authMiddleware,这样我就可以控制它的行为,而不必为每个测试用例提供有效/无效的JWT 当我在测试中尝试存根authMiddleware时,我意识到expressapp使用了authMiddleware的实际实现,而不是模拟的实现 在模拟authMiddleware之后,我尝试使用t
authMiddleware
,这样我就可以控制它的行为,而不必为每个测试用例提供有效/无效的JWT
当我在测试中尝试存根authMiddleware
时,我意识到expressapp
使用了authMiddleware
的实际实现,而不是模拟的实现
在模拟authMiddleware
之后,我尝试使用typescript的动态导入导入app
,但也不起作用
authMiddleware.ts
import{Request,Response,NextFunction}来自“express”;
导出默认类验证中间件{
verifyToken(请求:请求,响应:响应,下一步:下一步功能):无效{
log('verifyToken的实际实现被调用!');
//验证令牌
next();
}
}
我刚刚解释了在中发生的事情,但只给出了解决方法
经过几番思考,我相信克服这一问题的最佳方法是从模块中删除全局状态,并将整个初始化代码捕获到显式调用的函数(或类,如果您愿意)中,以便为每个测试创建服务器。即,将您的体系结构更改为:
// router.ts
export function createRouter() {
/// ...
router.post('/', authMiddleware.verifyToken, subjectController.createSubject);
return router;
}
// app.ts
import { createRouter} from "./router.js"
export function createApp() {
///same code as currently, but in function
app.use('/subject', createRouter());
}
现在,您可以在每个设置回调中创建新的“应用程序”:
// test.ts
beforeEach(async () => {
sinon.stub(AuthMiddleware.prototype, 'verifyToken').callsFake((req: Request, res: Response, next: NextFunction): void => {
...
});
app = (await import('../../../src/app')).createApp(); // note that we create new app for each test, so you're not polutting global state of app
});
除其他外,这种方法有许多优点:
- 您可以为不同的测试模拟不同的函数李>
- 您正在有效地从代码中删除“隐式单例” 存在是你问题的根本原因