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

如何使用Jest测试独立TypeScript文件并断言notify方法被调用

Jest测试立即执行TypeScript脚本的方案

你要测试的代码是顶层立即执行的异步函数(IIFE),导入文件时会自动运行,所以要提前完成所有依赖mock,再导入测试文件,具体实现步骤如下:

1. 核心思路

  • 提前mock所有外部依赖:NotificationService、日志工具、process.exit,避免真实逻辑执行影响测试
  • 所有mock操作必须放在导入测试文件之前,否则IIFE执行时mock还未生效
  • 异步IIFE需要等待微任务队列清空后再执行断言

2. 完整测试代码示例

假设你的源文件名为notify-task.ts,测试文件notify-task.test.ts代码如下:

// -------------- 第一步:提前mock所有外部依赖(必须写在导入测试文件之前)--------------
// mock NotificationService,将notify方法替换为jest mock函数
const mockNotify = jest.fn();
jest.mock('./notification-service', () => ({
  NotificationService: jest.fn().mockImplementation(() => ({
    notify: mockNotify
  }))
}));

// mock日志工具,避免真实打印
const mockLoggerError = jest.fn();
jest.mock('./logger', () => ({
  logger: {
    error: mockLoggerError
  }
}));

// mock process.exit,避免测试进程被强制退出
const mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(() => undefined as never);

// mock常量SERVICE_NAME
jest.mock('./constants', () => ({
  SERVICE_NAME: 'test-notify-service'
}));

// -------------- 第二步:导入测试文件(导入后IIFE会立即执行)--------------
import './notify-task';

// -------------- 第三步:编写测试用例 --------------
describe('独立通知任务脚本测试', () => {
  beforeEach(() => {
    // 每次测试前清空所有mock的调用记录
    jest.clearAllMocks();
  });

  it('正常执行时会调用notify方法,传入参数为test', async () => {
    // 等待异步IIFE的所有微任务执行完成
    await Promise.resolve();

    // 断言NotificationService被正确实例化
    expect(require('./notification-service').NotificationService).toHaveBeenCalledTimes(1);
    // 断言notify方法被调用,参数符合预期
    expect(mockNotify).toHaveBeenCalledTimes(1);
    expect(mockNotify).toHaveBeenCalledWith('test');
    // 正常场景不会触发错误日志和进程退出
    expect(mockLoggerError).not.toHaveBeenCalled();
    expect(mockProcessExit).not.toHaveBeenCalled();
  });

  it('执行异常时会打印错误日志并退出进程', async () => {
    // 重置模块缓存,方便重新导入文件触发IIFE执行
    jest.resetModules();
    // 模拟notify方法抛出异常
    const testError = new Error('通知发送失败');
    mockNotify.mockRejectedValueOnce(testError);

    // 重新导入测试文件
    import('./notify-task');
    // 等待异步逻辑执行完成
    await Promise.resolve();

    // 断言错误日志和进程退出逻辑被正确触发
    expect(mockLoggerError).toHaveBeenCalledTimes(1);
    expect(mockLoggerError).toHaveBeenCalledWith(testError, 'error while running test-notify-service');
    expect(mockProcessExit).toHaveBeenCalledWith(1);
  });
});

3. 注意事项

  • 如果你的依赖导入路径和示例不同,需要对应修改jest.mock的第一个参数为实际导入路径
  • 如果notify是同步方法,也需要保留await Promise.resolve()的逻辑,确保IIFE执行完成后再做断言
  • 多场景测试时必须调用jest.resetModules()清空模块缓存,否则重复导入不会重新执行IIFE

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 19:30:02