- 我有一个web应用程序,它使用window.applicationCache为 脱机访问。
- 我管理appCache (例如,检查/更新/交换缓存)的所有代码都封装在一个“缓存控制器”对象中。
我有单元测试来测试我的 “缓存控制器”功能。对于测试,我暂时用 替换本机window.applicationCache对象与我自己的模拟 版本(因为我只想测试我的代码,而不是浏览器 appCache实现),例如。模拟全局窗口对象中的require.js
window.applicationCache = { /* my appCache mock */ }; // unit tests run here. Code under test references window.applicationCache.
前一段时间(大约镀铬16)这种方法非常完美。然后,Chrome 17在Windows平台上的Mac &中删除了修补浏览器的默认window.applicationCache属性的功能(但奇怪的是,Chrome for Linux的所有版本(包括Chrome 26在内)都可以正常工作。当时,我logged a Chromium bug为此;但不幸的是,该错误报告仍列为“未经证实”。
无论如何,我只是使用require.js作为模块加载器,将我的应用程序从传统的'浏览器全局变量'(即通过脚本标记加载* .js文件;所有JS对象是全局变量)移植到AMD样式的模块。
AMD(或CommonJS)的好处之一是依赖注入,其中代码获取本地引用到任何依赖对象,而不是依赖全局引用,例如。
require(['foo'], function(Foo) {
var bar = new Foo();
});
...这使得它很容易做到的对象嘲讽,因为你可以配置模块加载到通过模拟对象为测试模式时,“富”。我希望通过转向依赖注入,我可以解决我的applicationCache问题(因为传递到我的模块中的“窗口”引用可能是全局窗口对象或模拟对象)。
但是我不知道如何require.js注入'窗口'作为依赖到我的模块?
是否有可能(可能使用shim config?)来定义'窗口'模块;然后可以将它传递给在全局“窗口”对象上运行的任何代码?所以我可以这样做:
require(['???'], function(window) {
// 'window' here is the real window object, or for testing it's a mock window object
window.applicationCache.update();
});
... where'???'是指窗口对象的模块名称。
或者我需要定义自己的模块,导出“窗口”,它可以不同地映射单元测试,例如。
// window.js
define(function() {
return window; // real global window object
});
// window-mock.js
define(function() {
return {
applicationCache: { /* mock version of appCache */ }
}
});
// for unit testing, remap 'window' to the mock version
require.config({
map: {
"cache-controller": {
"window": "window-mock"
}
}
});
// cache-controller.js
require(['window'], function(window) {
window.applicationCache.update();
});