微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决使用 sinon 如何以一种比 sinon.restore 之后删除所有痕迹的方式来伪造/存根/模拟一个不存在的 JS API?

在运行我的测试时,我有时想为我的测试提供 API。我希望在测试期间单独定义此 api,因此我想确保 sinon.restore() 删除此测试 api。这不会取代现有的 JS API。 (例如。不是像 window.requestAnimiationFrame 这样的东西)。假定此 API 全局存在。 (例如,在全局/窗口对象上)

现在如果我不关心删除这个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 !!

所以我改用存根:

// 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 之后删除它的所有痕迹?

解决方法

简而言之,您不能使用 sinon.restore() 执行此操作。我们明确地让 API 尝试替换不存在的道具,但我们在 sinon 团队中对此进行了更长时间的讨论,基本上came to the the conclusion that we should add something like sinon.define().仍然没有人制作该功能请求进入一个实际问题,所以如果我是你,我只会提交一个新问题作为你对 Sinon Github 跟踪器的功能请求。很多人都喜欢这个功能,而且实现起来并不难,所以只要让它可见:)

要使用当今现有的机器来实际执行此操作,我可能会按照评论中提到的方式执行此操作:在挂钩之前/之后使用您的测试框架来设置和拆除手动构建的存根。

如果我自己做,我可能会重做代码,以便能够将 API 注入您的模块,而不是依赖全局变量。这是另一种思想流派,因此,无论您的船如何:)

,

鉴于 'oligofren' 有助于澄清 sinon.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');

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?