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

如何用Sinon模拟fs模块的statSync函数?多次尝试未生效

解决Sinon无法Stub fs.statSync的问题

问题概述

编写了一个判断文件夹创建时间是否超过24小时阈值的函数,测试时尝试用Sinon Stub fs模块的statSync方法,但始终无法生效:控制台打印真实的stat结果,Stub的callCount为0,尝试了returns、callsFake、resolves等多种Stub方式均无效。

核心原因

原函数中**statSync的导入方式**导致Stub失效:如果原函数是直接导入单个方法import { statSync } from 'fs',而测试代码中Stub的是fs.statSync,这两个并非同一个引用。ES模块的单个导入会直接绑定原始方法,Sinon对fs对象上的statSync进行Stub不会影响原函数中已导入的独立statSync方法。

解决方案

方案1:修改原函数的导入方式

将原函数改为导入整个fs模块,调用fs.statSync,这样测试中对fs.statSync的Stub就能覆盖到实际调用:

import * as fs from 'fs';

export const isFolderOlderThanThreshold = (path: string) => {
  console.log('isFolderOlderThanThreshold');
  const rootFolderStat = fs.statSync(path); // 使用fs.statSync而非单独导入的statSync
  console.log('rootFolderStat = ', rootFolderStat);
  const dateToCompare = new Date();
  dateToCompare.setTime(dateToCompare.getTime() - (24 * 60 * 60 * 1000));
  console.log('Creation time of folder %s is %s and threshold time is %s', path, rootFolderStat.birthtime, dateToCompare);
  return rootFolderStat.birthtimeMs <= dateToCompare.getTime();
};

方案2:使用proxyquire替换单个导入的方法

如果不想修改原函数的导入逻辑,可以用proxyquire工具在测试时替换原函数中导入的statSync:

  1. 先安装依赖:
npm install proxyquire --save-dev
  1. 修改测试用例:
import proxyquire from 'proxyquire';
import sinon from 'sinon';
import * as fs from 'fs';

it('should check created time in upload folder', () => {
    storageRepository.stubs.getRootStorageLocation.returns(rootStorageLocation);
    const date = new Date('2023-02-21T08:16:25.580Z');
    const obj = { birthtimeMs: BigInt(date.getTime()), birthtime: date } as fs.BigIntStats;
    const statSyncStub = sinon.stub().returns(obj);

    // 用proxyquire加载目标模块,替换其中的statSync
    const { isFolderOlderThanThreshold } = proxyquire('../path/to/your/module', {
        'fs': { statSync: statSyncStub }
    });

    const result = isFolderOlderThanThreshold(join(rootStorageLocation, 'aaa'));
    // 断言结果:2023年的时间早于当前时间减24小时,返回true
    expect(result).to.be.true;
    // 断言Stub被调用过一次
    expect(statSyncStub.calledOnce).to.be.true;
    console.log('statSyncStub.callCount = ', statSyncStub.callCount);
});

测试用例关键修正点

  • 同步方法不能用resolves:statSync是同步方法,Stub时要用returns或callsFake,不能用resolves(resolves是给异步Promise函数用的)。
  • 避免不必要的IO操作:测试时无需实际创建/删除文件夹,因为已经Stub了statSync,直接模拟返回值即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:20:32