我的单元测试在 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/