You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jest中测试TypeScript类构造函数的参数数量与类型?

测试TypeScript类构造函数的参数数量与类型

假设我在MyClass.ts中定义了这样一个简单类:

export class MyClass {
  private foo:string;
  private bar:number;

  constructor(foo:string, bar:number){
    this.foo = foo;
    this.bar = bar;
  }
}

我需要编写测试用例,检查MyClass构造函数的参数数量是否正确,理想情况下还能校验参数类型与顺序。也就是说,当MyClass被修改成以下任意一种情况时,测试要失败:

  • 情况1:参数数量不足
export class MyClass {
  constructor(foo:string){}
}
  • 情况2:参数数量过多
export class MyClass {
  constructor(foo:string, bar:number, a:string){}
}
  • 情况3:参数顺序颠倒
export class MyClass {
  constructor(bar:number, foo:string){}
}
  • 情况4:参数类型任意化
export class MyClass {
  constructor(a:any, b:any){}
}

解决方案

1. 检查构造函数参数数量

JavaScript/TypeScript中,函数的length属性会返回其声明的参数个数,直接用这个特性就能快速校验参数数量:

import { MyClass } from './MyClass';

test('MyClass构造函数参数数量应为2个', () => {
  expect(MyClass.length).toBe(2);
});

这个测试可以直接拦截参数数量过多或过少的情况(比如上面的情况1、情况2)。

2. 校验参数类型与顺序

TypeScript编译后会擦除类型信息,所以需要通过运行时验证或元数据来实现类型与顺序的校验:

方法一:通过实例属性反向验证

传入特定类型的参数,检查实例的私有属性是否正确接收了对应值,以此间接验证参数的类型和顺序:

import { MyClass } from './MyClass';

test('MyClass构造函数参数类型与顺序正确', () => {
  const testFoo = '测试字符串';
  const testBar = 12345;
  
  const instance = new MyClass(testFoo, testBar);
  
  // 由于foo和bar是私有属性,通过类型断言绕过TypeScript的访问限制
  expect((instance as any).foo).toBe(testFoo);
  expect((instance as any).bar).toBe(testBar);
});

这个测试能覆盖所有异常情况:参数顺序颠倒时,属性值会和预期不符;参数类型任意化且未正确赋值时,属性会是undefined或错误类型的值。

方法二:使用反射元数据直接校验类型

借助reflect-metadata库保留TypeScript的类型元数据,实现更直接的类型校验:

  1. 安装依赖:
npm install reflect-metadata --save-dev
  1. 修改tsconfig.json,启用元数据相关配置:
{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    // 其他已有配置...
  }
}
  1. 给MyClass添加装饰器(用于触发元数据生成):
import 'reflect-metadata';

// 装饰器无需额外逻辑,仅用于让TypeScript生成参数类型元数据
@Reflect.metadata('design:paramtypes', [String, Number])
export class MyClass {
  private foo:string;
  private bar:number;

  constructor(foo:string, bar:number){
    this.foo = foo;
    this.bar = bar;
  }
}
  1. 编写测试用例:
import 'reflect-metadata';
import { MyClass } from './MyClass';

test('MyClass构造函数参数类型与顺序符合预期', () => {
  const paramTypes = Reflect.getMetadata('design:paramtypes', MyClass);
  expect(paramTypes).toEqual([String, Number]);
});

这个测试会直接获取构造函数的参数类型元数据,一旦参数类型、顺序发生变化,测试就会失败。


内容的提问来源于stack exchange,提问作者scibuff

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 21:55:22