使用sinon进行uuid桩数据处理

11

我正在更新我的项目依赖关系,但遇到了一些问题...

我的单元测试使用以下存根(stub)完美运行。但是在最新版本的UUID中,似乎出现了问题。有什么建议可以解决吗?

这些是从代码中提取的简单示例,以说明我使用的存根uuid功能的方法以及我如何在代码中使用uuid。

import * as uuid from 'uuid'

sinon.stub(uuid, 'v4').returns('some-v4-uuid')
import * as uuid from 'uuid'

const payload = {
  id: uuid.v4()
}

依赖项版本

  • "uuid": "7.0.1"
  • "sinon": "9.0.0"

这里是代码

这里是测试

3个回答

11

考虑到 uuid@7 模块使用 Object.defineProperty 导出版本信息,我认为 无法进行存根化。这很烦人,但你可能需要在 uuid 上添加一个抽象层,并对其进行存根化。


3
现在只使用 uuid@3.4.0。在这个版本上,存根工作正常,并且它稳定且没有漏洞。 - Skaleb

1
Oriol记功:
// monkey-patch Object.defineProperty to allow the method to be configurable before importing uuid:
const _defineProperty = Object.defineProperty;
let _v4;
Object.defineProperty = function(obj, prop, descriptor) {
  if (prop == 'v4') {
    descriptor.configurable = true;
    if (!_v4) { _v4 = descriptor.value; }
  }

  return _defineProperty(obj, prop, descriptor);
};

import * as uuid from 'uuid';

// Initialise your desired UUIDs
const uuids = [
    'c23624e9-e21d-4f19-8853-cfca73e7109a',
    '804759ea-d5d2-4b30-b79d-98dd4bfaf053',
    '7aa53488-ad43-4467-aa3d-a97fc3bc90b8'
];

// stub it yourself
Object.defineProperty(uuid, 'v4', { value: () => uuids.shift() });

// and then if you need to restore:
Object.defineProperty(uuid, 'v4', { value: _v4 });
Object.defineProperty = _defineProperty;

这有点不太正规,但是今天我能找到的唯一答案是,如果您不愿意或无法重构代码以使uuid更容易存根,则只能如此。 - Okiba

-1
你可以创建一个新文件(uuid.js)并像这样操作
// uuid.js
const uuid = require('uuid');
    
const v4 = () => uuid.v4();
    
module.exports = { v4 };

// testcase
const uuid = require('uuid.js');//This isn't the actual npm library
const sinon = require('sinon');

describe('request beta access API', () => {
const sandbox = sinon.createSandbox();
    
sandbox.mock(uuid).expects('v4')
 .returns('some-v4-uuid');
    
 //Testcases
    
});

1
这不会起作用,因为 uuid 中的默认导出已被移除。现在必须以不同的方式进行导入。https://www.npmjs.com/package/uuid#user-content-default-export-removed - ItsGeorge
1
@bkmalan,您可能正在使用uuid 3.x.x或更早版本。 - James Webb
1
根据文档(https://www.npmjs.com/package/uuid#user-content-default-export-removed),从版本3开始,您不能像 const uuid = require('uuid'); 这样要求默认导出了。现在没有默认导出,因此会产生错误。 - ItsGeorge
@bkmalan,是的,但原始问题是关于存根v4函数的。当您像使用require那样将v4导入为uuidv4时,您无法存根v4函数,因为没有v4函数可以在uuidv4上调用,您只需直接在代码中导入和调用uuid4。以前,您会导入uuid,调用uuid.v4并在测试中存根uuid.v4。现在新的导入结构使这成为不可能,因此您必须像所选答案所说的那样,“在uuid上面放一个抽象层”,以便能够在测试中存根该函数。 - ItsGeorge
1
@ItsGeorge,我同意没有直接存根UUID v3+的方法。就像被接受的答案一样,这就是我在UUID之上实现抽象层的方式。在实现后,我在测试用例和其他函数中都使用了抽象层。 - bkmalan
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接