使用sinon如何伪造/存根/模拟一个不存在的JS API的方式比sinon.恢复之后删除它的所有痕迹?



在运行测试时,我有时想为我的测试提供一个API。我希望仅在测试期间定义此api,因此我希望确保sinon.restore()删除此测试api。这不是替换现有的JS API。(如。不是像window.requestAnimiationFrame那样的东西。假定此API是全局存在的。(如。在全局/window对象上)

现在,如果我不关心删除这个API,在测试完成后,我将做以下操作:

globalAPIObject.someTestApi = sinon.fake.returns('something');

然而sinon.restore不会/不能删除globalAPIObject。someTestApi .

我希望能够像stub一样使用fake。(但sinon不提供)

// !! this API doesn't exist !!
sinon.fake(globalAPIObject, 'someTestApi').returns('something');
// !! this API doesn't exist !!

所以我用stub代替:

// This doesn't work if globalAPIObject.someTestAPi doesn't already exist.
sinon.stub(globalAPIObject, 'someTestApi').returns('something');

然而,这只适用于替换已经存在的道具/函数,所以我必须这样做:

globalAPIObject.someTestApi = () = {};
sinon.stub(globalAPIObject, 'someTestApi').returns('something');

这是不理想的。(如globalAPIObject。someTestApi不会在测试结束时被sinon.restore()删除。而且我宁愿只写一行)

因为我猜提供一个不存在的API是很多人想做的事情,我猜我错过了一些明显的东西。

假冒/存根/模拟新API的最佳方式是什么?恢复之后删除它的所有痕迹?

总之,使用sinon.restore()无法做到这一点。我们明确地制作了API,试图替换不存在的道具,但我们在sinon团队对此进行了更长时间的讨论,最终得出结论,我们应该添加sinon.define()之类的东西。然而,没有人把这个功能请求变成一个实际的问题,所以如果我是你,我会把这个作为你的功能请求提交给Sinon Github跟踪器。很多人会喜欢这个功能,它真的不是很难实现,所以只要让它可见:)

要真正做到这一点,使用今天现有的机器,我可能只是做在评论中提到的:使用你的测试框架之前/之后挂钩设置和拆除手动构建的存根。

如果我要自己做,我可能会重新编写代码,以便能够将API注入到您的模块中,而不是依赖全局变量。这是另一种思想流派,所以,不管你的船撞了什么

考虑到'oligofren'有助于澄清这个问题。Stub不是我们的用例,我们只是扩展了它。

// sinonExtensions.js
import sinon from "sinon";
if (sinon.stub !== enhancedStub)
{
sinon.originalStub = sinon.stub;
sinon.stub = enhancedStub;
}
function enhancedStub(obj, method)
{
if (!obj)
return sinon.originalStub();
if (!obj[method])
obj[method] = () => { };
return sinon.originalStub(obj, method);
}
// TODO: enhance sinon.restore to return non-existing methods to undefined

与其他sinon导入的内容一起导入:

import sinon, { mock } from "sinon";
import sinonChai from 'sinon-chai';
import 'sinonExtensions.js';
chai.use(sinonChai);

这对我们当前使用的所有sinon.stub都是有益的。

现在这个快乐的工作:

sinon.stub(globalAPIObject, 'someTestApi').returns('something');

相关内容

  • 没有找到相关文章

最新更新