Javascript 在 NodeJS 中测试对象相等性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12629981/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Testing objects equality in NodeJS
提问by Julien Genestoux
We are writing tests for a program. We want to write a functionnal test that verifies that the output of the program matches some expectation. The object returned is a complex JS object (with nested objects, many properties... etc).
我们正在为程序编写测试。我们想编写一个功能测试来验证程序的输出是否符合某些预期。返回的对象是一个复杂的 JS 对象(带有嵌套对象、许多属性......等)。
We want to test that this obviously matches what we need. Up until now, we were "browsing" the object and the expected outcome, checking for each property, and each nested object. That is very cumbersome and we were wondering if there was any library that would 'build' all the tests, based just on the object. Something like this for example.
我们想测试这显然符合我们的需要。到目前为止,我们一直在“浏览”对象和预期结果,检查每个属性和每个嵌套对象。这非常麻烦,我们想知道是否有任何库可以仅基于对象“构建”所有测试。例如这样的事情。
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].
[In the example, I have simplified the complexity of our object...]
[在示例中,我简化了我们对象的复杂性...]
I should insist on the fact that we need a piece of code that is smart enough to tell us what is different, rather than just tell us that the 2 objects are different. We now about deep equality, but we haven't found anything that actually tells us the differences.
我应该坚持这样一个事实,即我们需要一段足够聪明的代码来告诉我们什么是不同的,而不是仅仅告诉我们这两个对象是不同的。我们现在谈论深度平等,但我们还没有发现任何能真正告诉我们差异的东西。
回答by DeadAlready
Node has the built in assertmodule meant for testing. This has a method called deepEqualfor deep equality checking.
Node 具有用于测试的内置断言模块。这有一个称为deepEqual的方法,用于深度相等性检查。
Function signature is:
函数签名为:
assert.deepEqual(actual, expected, [message])
Quickly written function for testing deepEquality and returning diff:
用于测试 deepEquality 并返回差异的快速编写函数:
// 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;
}
回答by Daff
JavaScript doesn't support object deep equality out of the box and I am not aware of anything built into the NodeJS API either.
JavaScript 不支持开箱即用的对象深度相等性,我也不知道 NodeJS API 中内置的任何内容。
My bet would probably be Underscoreand the isEqualfunction.
我的赌注可能是Underscore和isEqual函数。
npm install underscore
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
Although most Node testing frameworks should also contain an object deep equality assertion but you didn't mention which one you are using.
虽然大多数 Node 测试框架还应该包含一个对象深度相等断言,但您没有提到您使用的是哪个。
回答by justwondering
deep-diffdoes what OP is asking for. It can compare two javascript objects / JSON objects and list the differences in a way that your code can access.
deep-diff 满足OP 的要求。它可以比较两个 javascript 对象/JSON 对象,并以您的代码可以访问的方式列出差异。
This is an old question so this library probably didn't exist at the time the question was asked.
这是一个老问题,因此在提出问题时可能不存在该库。
回答by Brian Renzenbrink
While I think the basics of object comparison have already been covered (see hereand others), if you're looking for a quick and dirty way to execute these tests and see the diff between two non-equal objects, you can just run your tests using nodeunit within the Webstorm IDE (here)
虽然我认为已经涵盖了对象比较的基础知识(请参阅此处和其他内容),但如果您正在寻找一种快速而肮脏的方法来执行这些测试并查看两个不相等对象之间的差异,则可以运行您的在 Webstorm IDE 中使用 nodeunit 进行测试(这里)
Webstorm integrates particularly well with nodeunit, and for any test.equals() or test.deepEquals() assertions it provides a viewable diff with highlighting to show your descrepencies. I highly recommend the IDE for how well it integrates testing into my js development cycle.
Webstorm 与 nodeunit 集成得特别好,对于任何 test.equals() 或 test.deepEquals() 断言,它提供了一个可查看的差异,突出显示以显示您的差异。我强烈推荐 IDE,因为它可以很好地将测试集成到我的 js 开发周期中。
Now, if you need the results of that test/diff to be accessible within your code, this obviously isn't enough for you and I'd recommend copying a couple of the deepEquals comparators from the first link I listed.
现在,如果您需要在代码中访问该测试/差异的结果,这显然对您来说还不够,我建议从我列出的第一个链接中复制几个 deepEquals 比较器。
Good luck,
祝你好运,
Brian
布赖恩
回答by toshiomagic
This is a simple/flexible deep diff function I wrote using Lodash:
这是我使用 Lodash 编写的一个简单/灵活的深度差异函数:
_.merge(obj1, obj2, function (objectValue, sourceValue, key, object, source) {
if ( !(_.isEqual(objectValue, sourceValue)) && (Object(objectValue) !== objectValue)) {
console.log(key + "\n Expected: " + sourceValue + "\n Actual: " + objectValue);
}
});
You can replace the console.log()
statement with whatever comparison logic you need. Mine just prints out the differences to the console.
您可以console.log()
使用您需要的任何比较逻辑替换该语句。我的只是将差异打印到控制台。