我编写了一个函数,根据David Walsh的Get Query String Parameters获取给定查询字符串的值。
export const getQueryStringValue = (name) => {
const formattedName = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
const regex = new RegExp(`[\\?&]${formattedName}=([^&#]*)`);
const results = regex.exec(window.location.search);
return results === null
? ''
: decodeURIComponent(results[1].replace(/\+/g, ' '));
};
我已经基于How to mock window.location.href with Jest + Vuejs?编写了对该功能的测试。
it('should return query string value', () => {
global.window = Object.create(window);
const url = 'http://dummy.com?foo=bar';
Object.defineProperty(window, 'location', {
value: {
href: url
}
});
expect(getQueryStringValue('foo')).toBe('bar');
});
但是,当我运行测试时,出现以下错误。
expect(received).toBe(expected) // Object.is equality
Expected: "bar"
Received: ""
并且当我管理日志window.location.search
时,它返回undefined
。
console.log __tests__/getQueryStringValue.test.js:14
undefined
即使Window.location href包含查询字符串(undefined
),为什么Window.location搜索仍返回?foo=bar
?设置href应该不够吗?
Window.location href设置为jsdom does not currently handle navigation时,不会自动模拟Window.location搜索。您可以通过几种方法来解决该错误。
选项1:设置Window.location搜索
it('should return query string value', () => {
global.window = Object.create(window);
Object.defineProperty(window, 'location', {
value: {
search: '?foo=bar'
}
});
expect(getQueryStringValue('foo')).toBe('bar');
});
选项2:将Window.location设置为新的URL
实例
URL
来源: it('should return query string value', () => {
global.window = Object.create(window);
Object.defineProperty(window, 'location', {
value: new URL('http://dummy.com/?foo=bar')
});
expect(getQueryStringValue('foo')).toBe('bar');
});
带有窗口原型的新对象显然与您当前的窗口不同。 global
也未定义。我收到此错误:can't redefine non-configurable property "location"
。获取类似这样的查询参数:
const getQueryParams = url=>{
const o = {};
for(let i=0,s=url.replace(/^.+\?/, '').split('&'),b,p,v,l=s.length; i<l; i++){
b = s[i].split('='); p = decodeURIComponent(b[0]); v = decodeURIComponent(b[1]);
if(p in o){
if(o[p] instanceof Array){
o[p].push(v);
}
else{
o[p] = [o[p], v];
}
}
else{
if(!isNaN(v))v = +v;
o[p] = v;
}
}
return o;
}
// assumes raw url encode - may need to further parse for value+another
console.log(getQueryParams('http://dummy.com?foo=bar&foo=crazy&really=cool%20stuff&now=1'));
if(location.search.match(/^.+\?/))console.log(getQueryParams(location.search)); // should work on your site whith query params