我们正在为一个程序编写测试。我们想要编写一个功能测试,来验证程序的输出是否符合某些期望。返回的对象是一个复杂的JS对象(具有嵌套对象、许多属性...等)。
我们想要测试一下,这显然符合我们的需求。到目前为止,我们一直在“浏览”对象和预期结果,检查每个属性和每个嵌套对象。这非常麻烦,我们想知道是否有任何库可以仅基于对象‘构建’所有的测试。例如,像这样的东西。
var res = {
a: {
alpha: [1,2,3],
beta: "Hello",
gamma: "World"
},
},
b: 123,
c: "It depends"
}
};
var expectation = {
a: {
alpha: [1,2,4],
beta: "Hello",
gamma: "World"
},
},
b: 123,
c: "It depends"
}
};
assert(res, expectation) // -> Raises an error because res[a][b][2] is different from expectation[a][b][2].
在这个例子中,我简化了对象的复杂性...
我应该坚持这样一个事实,我们需要一段足够智能的代码来告诉我们什么是不同的,而不是仅仅告诉我们这两个对象是不同的。我们现在谈到了深度平等,但我们还没有发现任何真正能告诉我们区别的东西。
发布于 2012-09-28 05:20:36
Node具有用于测试的内置assert模块。这有一个名为deepEqual的方法,用于深度相等检查。
函数签名为:
assert.deepEqual(actual, expected, [message])
用于测试deepEquality和返回diff的快速编写函数:
// Will test own properties only
function deepEqualWithDiff(a, e, names){
var dif = {};
var aKeys = Object.keys(a);
var eKeys = Object.keys(e);
var cKeys = aKeys;
var dKeys = eKeys;
var c = a;
var d = e;
var names = {
c: names ? names['a'] : 'Actual',
d: names ? names['e'] : 'Expected'
}
if(eKeys.length > aKeys.length){
cKeys = eKeys;
dKeys = aKeys;
c = e;
d = a;
names = {
d: names ? names['a'] : 'Actual',
c: names ? names['e'] : 'Expected'
}
}
for(var i = 0, co = cKeys.length; i < co; i++){
var key = cKeys[i];
if(typeof c[key] !== typeof d[key]){
dif[key] = 'Type mismatch ' + names['c'] + ':' + typeof c[key] + '!==' + names['d'] + typeof d[key];
continue;
}
if(typeof c[key] === 'function'){
if(c[key].toString() !== d[key].toString()){
dif[key] = 'Differing functions';
}
continue;
}
if(typeof c[key] === 'object'){
if(c[key].length !== undefined){ // array
var temp = c[key].slice(0);
temp = temp.filter(function(el){
return (d[key].indexOf(el) === -1);
});
var message = '';
if(temp.length > 0){
message += names['c'] + ' excess ' + JSON.stringify(temp);
}
temp = d[key].slice(0);
temp = temp.filter(function(el){
return (c[key].indexOf(el) === -1);
});
if(temp.length > 0){
message += ' and ' + names['d'] + ' excess ' + JSON.stringify(temp);
}
if(message !== ''){
dif[key] = message;
}
continue;
}
var diff = deepEqualWithDiff(c[key], d[key], {a:names['c'],e:names['d']});
if(diff !== true && Object.keys(diff).length > 0){
dif[key] = diff;
}
continue;
}
// Simple types left so
if(c[key] !== d[key]){
dif[key] = names['c'] + ':' + c[key] + ' !== ' + names['d'] + ':' + d[key];
}
}
return Object.keys(dif).length > 0 ? dif : true;
}
发布于 2012-09-28 05:07:23
JavaScript不支持开箱即用的对象深度相等,我也不知道NodeJS应用程序接口中内置了什么。
我打赌可能是Underscore和isEqual函数。
npm安装下划线
var _ = require('underscore');
var moe = {name : 'moe', luckyNumbers : [13, 27, 34]};
var clone = {name : 'moe', luckyNumbers : [13, 27, 34]};
moe == clone;
=> false
_.isEqual(moe, clone);
=> true
尽管大多数Node测试框架也应该包含一个对象深度相等断言,但是您没有提到您正在使用哪一个。
发布于 2014-12-08 09:42:34
deep-diff做了OP要求的事情。它可以比较两个javascript对象/ JSON对象,并以您的代码可以访问的方式列出差异。
这是一个老问题,所以这个库在提出问题时可能还不存在。
https://stackoverflow.com/questions/12629981
复制相似问题