javascript - 我如何伪造全局上下文来隔离测试?

标签 javascript node.js unit-testing mocha.js sinon

我的单元测试在 node.js 中运行(使用 mocha、chai 和 sinon)。我正在测试的代码旨在在浏览器中运行。

一些代码定义全局事物,而其他代码期望有一个 window 对象,并将对象添加到 window。 (具体来说,我正在使用填充程序来模拟 ES6 的 Promise 对象。)到目前为止,我已经通过添加 global.window = global; 伪造了 window 对象,这只能让我到目前为止。当我想为下一组测试拆除我的假环境时,问题就来了。

我已经尝试在 before()beforeEach() 函数中执行我的 require() 调用,并且我已经手动尝试过删除在 after()afterEach() 函数中创建的对象。每次都会发生两件事之一。要么全局对象从一个测试 JS 文件持续到下一个,要么全局对象对于所有测试神秘地不存在。

我不确定这是否与 mocha 运行测试 JS 文件的方式或 require() 的工作方式有关,但我没有想法。肯定有人以前解决过这个问题吗?

最佳答案

您可以使用 Node 的 vm module 将“浏览器代码”与套件的其余部分隔离开来.对于您的情况,这可能就足够了。例如:

var vm = require("vm");

var window = {};
window.window = window;

vm.runInNewContext("foo = ['foo val'];", window);
console.log(window.foo);
console.log(window.window.foo);
console.log(window.window.foo === window.foo);
vm.runInNewContext("window.bar = ['bar val'];", window);
console.log(window.bar);
console.log(window.window.bar);
console.log(window.window.bar === window.bar);

关于 contextify package 的文档提到 vm 不能很好处理的用例(异步代码)。在这些情况下,您必须使用像 contextify 这样的工具,它可以完成 vm 的功能并且支持异步代码。

如果您需要在模拟通常存在于浏览器中的 API 的环境中运行浏览器代码,则有 jsdom ,我已经成功地使用它来测试导航 DOM 树的代码。 Jsdom 碰巧在内部使用 contextify 将浏览器代码与 Node 的其余部分隔离。

关于javascript - 我如何伪造全局上下文来隔离测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22313237/

相关文章:

unit-testing - 如何使用 Angular 翻译进行单元测试

javascript - 从 "obj.obj1.obj2.data' 这样的字符串创建深层对象

javascript - 使用 SweetAlert.js 在单独的 javascript 代码中调用函数。不同范围的问题

Javascript - 用不同的值替换具有相同类的元素

node.js - 用于项目和部署特定变量的 Azure DevOps 管道

javascript - node.js request.js 不并行触发请求

javascript - Kik Api 的 Webhook?

javascript - 使用 ngAnimate 时,通过 ng-if 删除元素会被延迟

php - 如何创建一个 Doctrine 实体的模拟对象?

java - 带有单元测试的 Xml Dom 库