【发布时间】:2026-01-31 10:00:01
【问题描述】:
对于漫长的任务,我们深表歉意。我试图尽可能清楚地解决我面临的问题。
我创建了一个 decorators utils library,在处理其中一个装饰器 (https://github.com/vlio20/utils-decorators/blob/master/src/after/after.ts) 时遇到了一个奇怪的行为。
装饰器被命名为“after”,它应该在执行装饰方法后执行不同的功能。但事情是这样的,如果函数返回一个 Promise,装饰器应该等待它被解析,然后才调用 after func。
相关代码如下:
if (resolvedConfig.wait) {
const response = await originalMethod.apply(this, args);
afterFunc({
args,
response
});
} else {
const response = originalMethod.apply(this, args);
afterFunc({
args,
response
});
}
正如你所看到的,我为装饰器提供了一个标志,以表明被装饰的方法是一个异步函数并且它返回一个 Promise。我很乐意通过以下代码阅读此标志:
const response = await originalMethod.apply(this, args);
afterFunc({
args,
response
});
基本上,我希望始终将await 放在执行原始方法之前,因为据我了解,在同步方法的情况下,await 不会做任何事情。
问题在于,当我按照上面的建议更改代码时,以下单元测试失败:
it('should verify after method invocation when method is provided', () => {
let counter = 0;
const afterFunc = jest.fn(() => {
expect(counter).toBe(1);
});
class T {
@after<T, void>({
func: afterFunc
})
foo(x: number): void {
return this.goo(x);
}
goo(x: number): void {
expect(counter++).toBe(0);
return;
}
}
const t = new T();
const spyGoo = jest.spyOn(T.prototype, 'goo');
t.foo(1);
expect(spyGoo).toBeCalledTimes(1);
expect(spyGoo).toBeCalledWith(1);
expect(afterFunc.mock.calls.length).toBe(1); // this line fails
});
我已经创建了这个精确测试失败的库的一个分支 (https://github.com/vlio20/utils-decorators/pull/new/after-issue)。
我的看法有什么问题?
【问题讨论】:
标签: javascript typescript unit-testing jestjs decorator