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

如何用Jest替换Mock TypeScript类中的只读属性

解决TypeScript中Jest Mock只读依赖属性的问题

先修正原代码的笔误:Consumer#useValue中的this.svc应为this.broker.svc,否则会直接报错。

给定类结构:

// value-service.ts
export class ValueService {
  fetchValue(): Promise<string> { ... }
}
// broker.ts
import {ValueService} from './value-service.js';

export class Broker {
  public readonly svc = new ValueService();
}
// consumer.ts
import {Broker} from './broker.js';

export class Consumer {
  constructor (private readonly broker: Broker) { }

  public async useValue() {
    const val = await this.broker.svc.fetchValue();
    return `${val}123`;
  }
}

在测试Consumer#useValue时,需要MockValueService#fetchValue,但Broker的svc是只读属性,自动Mock后出现运行时/类型问题,以下是无需自定义jest.mock工厂函数的简洁解决方案:


方法1:通过Object.defineProperty设置只读属性

利用JavaScript属性描述符,给Mock的Broker实例手动赋值svc,同时保持属性的只读特性:

import {jest} from '@jest/globals';
import {ValueService} from './value-service.js';
import {Broker} from './broker.js'
import {Consumer} from './consumer.js';

// 保留自动Mock
jest.mock('./value-service.js');
jest.mock('./broker.js');

describe('Consumer', () => {
  let instance: Consumer;

  beforeEach(() => {
    // 创建并配置Mock的ValueService
    const mockValueSvc = jest.mocked(new ValueService());
    mockValueSvc.fetchValue.mockResolvedValue('abc');

    // 创建Broker Mock实例
    const broker = jest.mocked(new Broker());

    // 给只读属性svc赋值
    Object.defineProperty(broker, 'svc', {
      value: mockValueSvc,
      configurable: true // 允许后续修改(可选)
    });

    instance = new Consumer(broker);
  });

  it('uses the value correctly', async () => {
    expect(await instance.useValue()).toBe('abc123');
  });
});

方法2:类型断言绕过TypeScript编译检查

如果不需要严格维护属性的只读特性,直接用类型断言跳过TypeScript的readonly约束:

// 在beforeEach中替换Object.defineProperty为:
(broker as any).svc = mockValueSvc;

// 或者更精确的类型断言:
(broker as Omit<Broker, 'svc'> & { svc: ValueService }).svc = mockValueSvc;

关键说明

  • 自动Mock的Broker实例默认不会初始化svc属性,因此需要手动赋值
  • TypeScript的readonly仅为编译时约束,运行时可通过属性描述符或类型断言修改
  • 需先配置好ValueService的Mock返回值,再赋值给Broker的svc,确保测试逻辑正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:39:53