TypeScript获取函数参数的函数名 实现Angular单参数函数测试
实现方案
方案1:改造test方法实现单参数调用
核心思路是在test方法内部处理this绑定,同时利用函数自带的name属性自动获取方法名,无需手动传字符串。
改造后的test方法代码:
import { isDevMode } from '@angular/core'; import { Observable } from 'rxjs'; export class AuthService { constructor( ... ) { // 调用时仅传方法引用即可 this.test(this.FunctionName) } test(fn: () => Observable<any>) { // 自动获取函数名 const funcName = fn.name; // 绑定当前类实例的this后执行函数,拿到返回的可观察对象 const sub = fn.call(this); // 仅在开发环境打印日志,避免生产环境输出 if (!isDevMode()) return; sub.subscribe( data => { console.group(`========== ${funcName}() TEST ===============`) console.log("Output Type:", typeof data) typeof data == 'object' ? console.table(data) : console.log(data); console.groupEnd() } ) } // 你的原有业务方法 FunctionName(): Observable<any> { // 原有逻辑 } }
如果方法需要传参,可扩展test方法支持参数传入:
test(fn: (...args: any[]) => Observable<any>, args: any[] = []) { const funcName = fn.name; const sub = fn.call(this, ...args); // 后续逻辑不变 } // 带参数的调用示例 this.test(this.FunctionName, [param1, param2])
方案2:装饰器实现无侵入式测试日志
如果不想在constructor里挨个调用测试方法,可以用装饰器标记需要测试的方法,方法执行时自动打印日志:
import { isDevMode } from '@angular/core'; import { Observable } from 'rxjs'; // 测试日志装饰器,可复用在所有类的方法上 function TestLog() { return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; descriptor.value = function (...args: any[]) { const result = originalMethod.apply(this, args); if (isDevMode() && result instanceof Observable) { result.subscribe(data => { console.group(`========== ${propertyKey}() TEST ===============`) console.log("Output Type:", typeof data) typeof data == 'object' ? console.table(data) : console.log(data); console.groupEnd() }) } return result; } return descriptor; } } // 使用示例 export class AuthService { // 仅需给要测试的方法加装饰器即可,无需额外调用代码 @TestLog() FunctionName(): Observable<any> { // 原有逻辑 } constructor() { // 不需要写任何测试调用代码,方法第一次执行时自动打印日志 } }
现有单元测试框架支持说明
Angular默认集成的Jasmine+Karma单元测试体系原生支持类似能力,你可以直接编写标准单测用例,不仅能打印输出,还能自动校验返回值是否符合预期:
// auth.service.spec.ts 单测文件示例 import { TestBed } from '@angular/core/testing'; import { AuthService } from './auth.service'; describe('AuthService', () => { let service: AuthService; beforeEach(() => { TestBed.configureTestingModule({}); service = TestBed.inject(AuthService); }); it('FunctionName 应返回预期数据', (done) => { service.FunctionName().subscribe(data => { // 自定义断言规则,不符合预期时单测会自动报错 expect(data).toBeTruthy(); expect(data.userId).toBeDefined(); done(); }) }); });
执行ng test命令即可运行所有单测,查看结果。
内容的提问来源于stack exchange,提问作者artur shevtsov
相关产品推荐
相关产品推荐

