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

升级uuid至v9后,如何使用Sinon stub uuid v4方法?

如何在uuid v9.0.0中用Sinon Stub v4方法?

问题背景

我将NodeJS及依赖版本更新后,尝试把uuid从v3.1.0升级到v9.0.0,测试中原先可用的Sinon Stub代码失效了。原代码如下:

sinon = require('sinon'),
uuid = require('uuid'),

before(async () => {
  uuidV4Stub = sinon.stub(uuid, 'v4').returns('RANDOM_ID');
});

查阅uuid的npm文档后发现,从uuid@7版本开始提供ECMAScript模块构建,支持Webpack、Rollup等打包工具的摇树优化,且移除了默认导出,需使用如下引入方式:

ES模块语法:

import { v4 as uuidv4 } from 'uuid'; uuidv4();

CommonJS语法:

const { v4: uuidv4 } = require('uuid'); uuidv4();

想问现在是否仍可以对uuid v4方法进行Stub?


解决方案

当然可以对uuid v4方法进行Stub,只是需要根据新的引入规则调整写法:

1. CommonJS环境下的写法

如果项目使用CommonJS语法,不要直接解构v4方法,保留对uuid模块的完整引用,这样就能正常Stub:

const sinon = require('sinon');
const uuid = require('uuid'); // 保留完整模块引用,不解构

before(async () => {
  uuidV4Stub = sinon.stub(uuid, 'v4').returns('RANDOM_ID');
});

// 业务代码中需使用uuid.v4(),而非解构后的局部变量

如果业务代码里用了解构写法(const { v4: uuidv4 } = require('uuid')),需要修改业务代码为从完整模块上调用v4,否则Stub不会生效——因为解构会把v4的引用复制到局部变量,Stub的是模块上的方法,无法影响局部变量的引用。

2. ES模块环境下的写法

ES模块的导出是只读的,无法直接修改,需要借助模块拦截工具来Stub,比如esmock(专门适配ES模块)或proxyquire(兼容CommonJS):

用esmock实现:
import sinon from 'sinon';
import esmock from 'esmock';

before(async () => {
  // 拦截uuid模块,替换v4为Stub
  const uuid = await esmock('uuid', {
    v4: sinon.stub().returns('RANDOM_ID')
  });
  // 确保业务代码引入的是被拦截后的uuid模块
});
用proxyquire实现:
const sinon = require('sinon');
const proxyquire = require('proxyquire');

before(async () => {
  const uuidStub = {
    v4: sinon.stub().returns('RANDOM_ID')
  };
  // 用proxyquire加载业务代码,替换其中的uuid模块为Stub
  const yourModule = proxyquire('./your-module.js', {
    'uuid': uuidStub
  });
});

关键注意事项

  • 避免直接解构v4方法后再Stub,解构会生成方法副本,Stub模块上的方法无法影响副本。
  • ES模块环境必须使用模块拦截工具,因为ES模块导出不允许直接修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:31:25