是否可以模拟 qUnit 测试的窗口位置对象
Is it possible to mock the window.location object for a qUnit test?
假设我有一个实用程序函数,为了简单起见(真实的东西很复杂且无关紧要),它返回当前窗口的查询字符串。
var someUtilityFunction = () {
return window.location.search.substring(1);
};
现在我想在 qUnit 中对这个函数进行单元测试(不确定测试工具是否相关):
test('#1 someUtilityFunction works', function () {
// setup
var oldQS = window.location.search;
window.location.search = '?key1=value1&key2=value2&key3=value3';
var expectedOutput = 'key1=value1&key2=value2&key3=value3';
// test
equals(someUtilityFunction(),
expectedOutput,
'someUtilityFunction works as expected.');
// teardown
window.location.search = oldQS;
});
这里的问题是将window.location.search
设置为不同的查询字符串会导致页面重新加载,实质上是进入无限请求循环。有没有办法在不对someUtilityFunction
函数进行任何更改的情况下模拟 window.location 对象?
几天前我们遇到了同样的问题。主要有两种方法:
重写代码
这可能不是最好的(如果有的话)解决方案,但请考虑将 window
对象传递给函数以使模拟更容易。更好的是,使用闭包并封装您的代码。这还有一些优点:
- 您可以影子全局变量
- 您可以使用私有本地变量
- 您可以避免命名冲突
- 阴影使嘲笑变得非常容易,只需传递其他内容即可
包装代码
您可以将所有代码包装在一个函数中,该函数将窗口对象模拟为局部变量。你基本上也有两种可能性:
假设这是模拟:
var customWindow = {
location: {
search: "",
hash: ""
}
};
使用闭合
var someUtilityFunction;
(function(window) {
// window is now shadowed by your local variable
someUtilityFunction = () {
return window.location.search.substring(1);
};
})(customWindow);
这用本地window
掩盖了全球window
。
使用 with
语句
虽然我通常强烈反对,但它确实可以解决这里的很多问题。由于它基本上重新映射了您的范围,因此您可以非常轻松地模拟您的环境。
// first some more preparation for our mock
customWindow.window = customWindow;
with(customWindow) {
// this still creates the var in the global scope
var someUtilityFunction = () {
// window is a property of customWindow
return window.location.search.substring(1);
};
// since customWindow is our scope now
// this will work also
someUtilityFunction = () {
// location is a property of customWindow too
return location.search.substring(1);
};
}
顺便说一句:我不知道search
属性是否与hash
属性具有相同的症状 - 即有时包括问号,有时不包括问号。但您可能需要考虑使用
window.location.search.replace(/^'?/, "");
而不是
window.location.substr(1);
我在使用window.history.pushState
方面取得了一些成功。请参阅此 StackOverflow 答案。对于每个单元测试,我调用一个函数setQueryString('var=something')
然后像这样实现:
function setQueryString(queryString) {
window.history.pushState({}, '', '?' + queryString);
}
你需要用 QUnit.module 的afterEach
方法清除查询字符串,否则你的查询字符串将被设置为最终测试的值,你会得到奇怪的结果。
- JavaScript窗口.位置不;我不在内容编辑器Web部件中工作
- JS窗口.位置不起作用
- 是否可以模拟 qUnit 测试的窗口位置对象
- 窗口位置href更改不会重新加载
- 如何在提交事件的底部设置窗口位置
- 如何在模式打开时更改窗口.位置
- 谷歌地图偏移标记/信息窗口位置(panTo/setCenter)
- 书签窗口位置javascript
- 单元测试窗口位置分配的角度问题
- JavaScript窗口位置延迟
- 如果类名和窗口位置匹配,请执行一些操作
- 会话丢失窗口.位置.href.
- JavaScript:window.conf,有两个窗口位置
- 如何从顶部获取窗口位置(以像素为单位)
- 如何在窗口位置之前显示消息 2 秒
- 休息标记位置 + 信息窗口位置
- 将标头添加到窗口.位置.路径名
- 窗口位置向上一级
- 将窗口位置替换为锚点
- 在谷歌地图中设置信息窗口位置