我怎样才能伪造全球背景来隔离testing?
我的unit testing运行在node.js中(使用mocha,chai和sinon)。 我正在testing的代码是为了在浏览器中运行。
一些代码定义全局的东西,而其他代码期望有一个window
对象,并将对象添加到window
。 (具体来说,我使用一个垫片来模拟ES6的Promise对象。)到目前为止,我通过添加global.window = global;
伪装窗口对象global.window = global;
到目前为止只能得到我 当我想拆除我的假环境下一组testing时,问题就出现了。
我已经尝试在before()
或beforeEach()
函数中执行我的require()
调用,并试图手动删除after()
或afterEach()
函数中创build的对象。 两件事中的一件发生在每次。 全局对象从一个testingJS文件持续到下一个,或者全局对象在所有的testing中都是神秘的。
我不确定这是否与摩卡运行testingJS文件或require()
如何工作的方式有关,但我没有想法。 以前有人解决过这个问题吗?
您可以使用Node的vm
模块将“浏览器代码”从套件的其余部分中分离出来。 这对你的情况可能已经足够了。 例如:
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);
关于symxtify包的文档提到了vm
无法很好处理的用例(asynchronous代码)。 在这些情况下,你必须使用像contextify
这样的工具,它做了什么vm
并支持asynchronous代码。
如果您需要在模拟浏览器中通常存在的API的环境中运行浏览器代码,那么我已经使用了jsdom ,并成功地testing了导航DOM树的代码。 Jsdom恰好在内部使用contextify
来将浏览器代码与Node的其余部分分离。
看看rewire
它可以让你:
- 注入其他模块或全局variables的模拟
- 泄漏私有variables
- 覆盖模块内的variables。