我想在TypeScript应用程序中利用CLS(本地连续存储),以便在某个地方可以放置元数据(例如用户ID,请求ID)以用于各种用途(例如记录),而不必在其中传递数据。每个方法调用。
我尝试同时使用cls-hooked和async-local-storage。但是,我无法从Jest单元测试中进行任何操作。
const als = require('async-local-storage');
als.enable();
// ... some code
describe('Authorization tests', () => {
test('Cannot call without correct scope', () => {
als.set('id', "123123123123");
expect(() => service.registerApp(ctxt, app)).toThrowError(AuthorizationError.NOT_AUTHORIZED);
});
});
上述基准id
的设置不会失败。
export function authorize(requiredPermissions: string[]) {
return (target: any, name: any, descriptor: any) => {
const protectedFunction = descriptor.value;
const als = require('async-local-storage');
console.log(`>>>>>>>>>My ID ${als.get('id')}`);
// ... some code
}
}
但是上面的代码只是输出:
>>>>>>>>>My ID null
我正在尝试的可能吗?预先感谢。
答案 0 :(得分:0)
由于Jest似乎不支持localStorage,因此您需要对其进行模拟。
我建议为此使用诸如https://www.npmjs.com/package/jest-localstorage-mock之类的库,否则您必须自己实现所有这些功能。
您需要将该库添加到devDependencies
中,并将其作为jest setupFile添加到package.json中:
{
"jest": {
"setupFiles": ["jest-localstorage-mock"]
}
}
您的测试应该在那之后通过。
答案 1 :(得分:0)
我能够解决我的问题而无需依赖jest-localstorage-mock
。简而言之,我的get(...)
调用试图在启用异步挂钩之前读取存储,这是the documentation的要求。另外,我的get(...)
呼叫尝试过早读取商店;因为我试图在装饰器中执行此操作,所以需要将get
调用移至descriptor.value
中,这实际上是在运行时执行的。
我更新后的生产代码现在包括enable()
调用,get(...)
调用在正确的位置,一切都很好:
const als = require('async-local-storage'); // pulled up to top of file
als.enable(); // added
export function authorize(requiredPermissions: string[]) {
return (target: any, name: any, descriptor: any) => {
const protectedFunction = descriptor.value;
descriptor.value = function() {
console.log(`>>>>>>>>>My ID ${als.get('id')}`); // moved into function
// ... some code
}
}
}