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

TypeScript中如何对模块内本地函数进行Stub?

解决TypeScript模块内函数Stub失效且保留类型安全的方案

核心思路

模块内直接调用函数时,TypeScript会编译为对函数本身的直接引用,而非模块导出对象上的方法,导致Sinon无法Stub生效。要解决这个问题,必须让模块内的函数调用指向模块导出对象的引用,同时通过类型化的引用保留类型检查能力。


方案1:自引用导入(推荐)

在模块内部通过import * as self导入自身,所有模块内跨函数调用都通过self对象进行,既保留完整类型提示,又能让Sinon的Stub逻辑生效。

模块代码示例(mymodule.ts)

import * as self from './mymodule';

export function someOtherFunc(): string {
  return 'original value';
}

export function someFunc(): string {
  // 用self调用同模块函数,而非直接调用someOtherFunc()
  return self.someOtherFunc();
}

测试代码示例(mymodule.test.ts)

const sinon = require('sinon');
const mymodule = require('./mymodule');
const { expect } = require('chai');

describe('mymodule', () => {
  it('should stub someOtherFunc successfully', () => {
    const stub = sinon.stub(mymodule, 'someOtherFunc').returns('stubbed value');
    
    const result = mymodule.someFunc();
    expect(result).to.equal('stubbed value');
    
    stub.restore();
  });
});

方案2:类型化exports别名

如果不想使用自引用导入,可以给exports添加类型断言,将其转换为当前模块的类型,避免exports被推断为any类型。

模块代码示例(mymodule.ts)

// 定义当前模块的类型
type MyModule = typeof import('./mymodule');
// 将exports断言为模块类型,得到类型化的引用
const self = exports as MyModule;

export function someOtherFunc(): string {
  return 'original value';
}

export function someFunc(): string {
  // 通过类型化的self调用同模块函数
  return self.someOtherFunc();
}

测试代码与方案1完全一致,Stub逻辑无需修改


方案生效原因

  • 两种方案都让模块内的函数调用指向模块导出对象的引用,而非函数本身的直接绑定,Sinon Stub的是模块导出对象上的方法,因此调用时会使用被Stub后的逻辑。
  • 无论是自引用导入还是类型化exports别名,都保留了TypeScript的完整类型检查,不会丢失类型安全。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 13:33:23