JS构造函数单元测试核心是验证对象创建、非法参数拒绝和状态一致性,专注初始化逻辑,覆盖合法、边界、非法三类输入,并确保属性赋值顺序正确。

JS 构造函数的单元测试,核心是验证它能否在各种输入下正确创建对象、拒绝非法参数、保持状态一致性——不依赖运行时环境,只关注初始化逻辑本身。
明确测试边界:只测构造行为,不测副作用
构造函数应专注初始化,不执行网络请求、DOM 操作或全局状态修改。测试前先确认它符合这一原则:
- 若构造函数里调用了 fetch 或 document.querySelector,先抽离为可注入的依赖(如传入一个 apiClient 参数)
- 避免在 constructor 中启动定时器、监听事件或写 localStorage
- 测试目标应是:给定输入 → 是否返回有效实例?是否抛出预期错误?
覆盖三类关键用例:合法、边界、非法输入
以一个典型用户类为例:
class User {constructor(name, age) {
if (!name || typeof name !== 'string' || name.trim() === '') {
throw new Error('name must be a non-empty string');
}
if (typeof age !== 'number' || age 150) {
throw new Error('age must be a number between 0 and 150');
}
this.name = name.trim();
this.age = age;
}
}
对应测试应包括:
- 合法输入:new User('Alice', 28) → 实例存在,name === 'Alice',age === 28
- 边界值:new User(' Bob ', 0) → name 被 trim,age 允许为 0;new User('Zoe', 150) → 合法上限
- 非法输入:new User('', 25) 应抛出错误;new User('Tom', -1) 和 new User('Tom', 151) 同样应报错;new User(null, 30) 也需捕获
用 Jest 验证错误抛出与实例结构
Jest 提供 toThrow 和 expect(...).toBeInstanceOf(...) 等断言,简洁可靠:
describe('User constructor', () => {test('creates instance with valid name and age', () => {
const u = new User('Lee', 33);
expect(u).toBeInstanceOf(User);
expect(u.name).toBe('Lee');
expect(u.age).toBe(33);
});
test('throws on empty name', () => {
expect(() => new User('', 20)).toThrow('name must be a non-empty string');
});
test('throws on invalid age', () => {
expect(() => new User('Sam', -5)).toThrow('age must be a number between 0 and 150');
});
});
注意初始化顺序陷阱(尤其含方法调用时)
如果构造函数内调用了实例方法(如 this.init()),必须确保所有属性已在调用前完成赋值,否则会访问 undefined:
// ❌ 危险写法constructor(data) {
this.init(); // 此时 this.config 还未定义
this.config = data;
}
// ✅ 正确顺序
constructor(data) {
this.config = data;
this.init(); // 此时 this.config 已就位
}
测试时可加一条断言:expect(() => new BadClass()).not.toThrow() 若它本不该崩溃,却因顺序错误而失败,说明构造逻辑有隐患。


















