如何编写一个永远不会在 JavaScript 中抛出 "Cannot read property '**' of undefined'" 的模拟对象
How to write a mock object that will never throw "Cannot read property '**' of undefined'" in JavaScript
为了编写单元测试,我想将一个对象传递给我的函数,模拟任何可能的 属性 - 注意:不是函数 属性.
当我有这样的功能时:
function someFunc (config){
var something = config.params.innerParams;
}
调用时 someFunc({})
会抛出 Cannot read property 'innerParams' of undefined'
.
如果config
中有很多递归属性,mock可能会非常耗时。有没有办法编写一个 "mock" 对象,我可以将其传递给我的函数以模仿任何结构?它可能会在访问时为所有属性赋值undefined,像这样:
var magic = new Magic(); //magical mock created
var a1 = magic.something; //undefined;
var a2 = magic.something.innerSomething; //undefined
var a3 = magic.something.innerSomething.farAwaySomething; //undefined
我只想避免 Cannot read property '*' of undefined'
被抛出。
您可以使用 ES6 Proxy
传递对不存在 属性 对象的访问权限。
在那种情况下,我会 return 对象本身。
但我认为,undefined
很难实现平等。
至少我不认识路(但我有一些想法)。
别忘了检查 Compatibility table。
function Magic() {
var res = new Proxy(this, { get(target, key, receiver) { return res } });
return res;
}
不能使它等于未定义,但可以false
(非严格):
function Magic() {
var res = new Proxy(this, { get(target, key, receiver) { return key === Symbol.toPrimitive ? Reflect.get(target, key, receiver) : res } });
res[Symbol.toPrimitive] = () => false;
return res;
}
在 FF44 中测试。
如果你有 Proxy
支持(目前是 Firefox、IE11 和 Edge),你可以传入
new Proxy({}, { get(a,b,p) { return p; } })
这是一个 Proxy
object,它允许访问任何名称的属性。访问时,每个这样的 属性 的值都是原始代理对象本身,从而允许 属性 访问的无限链。
属性 访问不会产生 undefined
,但是没有办法同时允许进一步的 属性 访问。
为了编写单元测试,我想将一个对象传递给我的函数,模拟任何可能的 属性 - 注意:不是函数 属性.
当我有这样的功能时:
function someFunc (config){
var something = config.params.innerParams;
}
调用时 someFunc({})
会抛出 Cannot read property 'innerParams' of undefined'
.
如果config
中有很多递归属性,mock可能会非常耗时。有没有办法编写一个 "mock" 对象,我可以将其传递给我的函数以模仿任何结构?它可能会在访问时为所有属性赋值undefined,像这样:
var magic = new Magic(); //magical mock created
var a1 = magic.something; //undefined;
var a2 = magic.something.innerSomething; //undefined
var a3 = magic.something.innerSomething.farAwaySomething; //undefined
我只想避免 Cannot read property '*' of undefined'
被抛出。
您可以使用 ES6 Proxy
传递对不存在 属性 对象的访问权限。
在那种情况下,我会 return 对象本身。
但我认为,undefined
很难实现平等。
至少我不认识路(但我有一些想法)。
别忘了检查 Compatibility table。
function Magic() {
var res = new Proxy(this, { get(target, key, receiver) { return res } });
return res;
}
不能使它等于未定义,但可以false
(非严格):
function Magic() {
var res = new Proxy(this, { get(target, key, receiver) { return key === Symbol.toPrimitive ? Reflect.get(target, key, receiver) : res } });
res[Symbol.toPrimitive] = () => false;
return res;
}
在 FF44 中测试。
如果你有 Proxy
支持(目前是 Firefox、IE11 和 Edge),你可以传入
new Proxy({}, { get(a,b,p) { return p; } })
这是一个 Proxy
object,它允许访问任何名称的属性。访问时,每个这样的 属性 的值都是原始代理对象本身,从而允许 属性 访问的无限链。
属性 访问不会产生 undefined
,但是没有办法同时允许进一步的 属性 访问。