dan*_*n27 52 javascript mocha.js node.js chai
我正在为我的应用程序使用node,mocha和chai.我想测试我的返回结果数据属性与我的模型对象之一是"对象类型".(与柴的实例非常相似).我只是想确认这两个对象具有相同的属性名称集.我特别对属性的实际值不感兴趣.
让我们说我有像下面的模型人.我想检查我的results.data是否具有与预期模型相同的属性.所以在这种情况下,Person具有firstName和lastName.
因此,如果results.data.lastName
与results.data.firstName
同时存在,那么它应该返回true.如果其中任何一个不存在,则应返回false.如果results.data具有任何其他属性(如results.data.surname),那么它将返回false,因为在Person中不存在姓氏.
该模型
function Person(data) {
var self = this;
self.firstName = "unknown";
self.lastName = "unknown";
if (typeof data != "undefined") {
self.firstName = data.firstName;
self.lastName = data.lastName;
}
}
Run Code Online (Sandbox Code Playgroud)
Cas*_*ter 87
您可以序列化简单数据以检查是否相等:
data1 = {firstName: 'John', lastName: 'Smith'};
data2 = {firstName: 'Jane', lastName: 'Smith'};
JSON.stringify(data1) === JSON.stringify(data2)
Run Code Online (Sandbox Code Playgroud)
这会给你类似的东西
'{firstName:"John",lastName:"Smith"}' === '{firstName:"Jane",lastName:"Smith"}'
Run Code Online (Sandbox Code Playgroud)
作为一个功能......
function compare(a, b) {
return JSON.stringify(a) === JSON.stringify(b);
}
compare(data1, data2);
Run Code Online (Sandbox Code Playgroud)
如果你像你说的那样使用柴,请查看http://chaijs.com/api/bdd/#equal-section
如果你只想检查钥匙......
function compareKeys(a, b) {
var aKeys = Object.keys(a).sort();
var bKeys = Object.keys(b).sort();
return JSON.stringify(aKeys) === JSON.stringify(bKeys);
}
Run Code Online (Sandbox Code Playgroud)
应该这样做.
sch*_*her 26
2这是一个简短的ES6可变版本:
function objectsHaveSameKeys(...objects) {
const allKeys = objects.reduce((keys, object) => keys.concat(Object.keys(object)), []);
const union = new Set(allKeys);
return objects.every(object => union.size === Object.keys(object).length);
}
Run Code Online (Sandbox Code Playgroud)
一点性能测试(MacBook Pro - 2,8 GHz Intel Core i7,Node 5.5.0):
var x = {};
var y = {};
for (var i = 0; i < 5000000; ++i) {
x[i] = i;
y[i] = i;
}
Run Code Online (Sandbox Code Playgroud)
结果:
objectsHaveSameKeys(x, y) // took 4996 milliseconds
compareKeys(x, y) // took 14880 milliseconds
hasSameProps(x,y) // after 10 minutes I stopped execution
Run Code Online (Sandbox Code Playgroud)
Rag*_*kkr 11
如果要检查两个对象是否具有相同的属性名称,可以执行以下操作:
function hasSameProps( obj1, obj2 ) {
return Object.keys( obj1 ).every( function( prop ) {
return obj2.hasOwnProperty( prop );
});
}
var obj1 = { prop1: 'hello', prop2: 'world', prop3: [1,2,3,4,5] },
obj2 = { prop1: 'hello', prop2: 'world', prop3: [1,2,3,4,5] };
console.log(hasSameProps(obj1, obj2));
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您确保只检查两个对象的可迭代和可访问属性.
编辑 - 2013.04.26:
可以通过以下方式重写上一个函数:
function hasSameProps( obj1, obj2 ) {
var obj1Props = Object.keys( obj1 ),
obj2Props = Object.keys( obj2 );
if ( obj1Props.length == obj2Props.length ) {
return obj1Props.every( function( prop ) {
return obj2Props.indexOf( prop ) >= 0;
});
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我们检查两个对象是否具有相同数量的属性(否则对象具有相同的属性,并且我们必须返回逻辑假)然后,如果数字匹配,我们将检查它们是否具有相同的属性属性.
奖金
可能的增强可能是引入类型检查以在每个属性上强制执行匹配.
如果你想像@speculees那样深入验证,这里有一个答案deep-keys
(披露:我是这个小包的维护者)
// obj1 should have all of obj2's properties
var deepKeys = require('deep-keys');
var _ = require('underscore');
assert(0 === _.difference(deepKeys(obj2), deepKeys(obj1)).length);
// obj1 should have exactly obj2's properties
var deepKeys = require('deep-keys');
var _ = require('lodash');
assert(0 === _.xor(deepKeys(obj2), deepKeys(obj1)).length);
Run Code Online (Sandbox Code Playgroud)
或者chai
:
var expect = require('chai').expect;
var deepKeys = require('deep-keys');
// obj1 should have all of obj2's properties
expect(deepKeys(obj1)).to.include.members(deepKeys(obj2));
// obj1 should have exactly obj2's properties
expect(deepKeys(obj1)).to.have.members(deepKeys(obj2));
Run Code Online (Sandbox Code Playgroud)
这是上面由schirrmacher提供的函数的深度检查版本。以下是我的尝试。请注意:
function objectsHaveSameKeys(...objects) {
const allKeys = objects.reduce((keys, object) => keys.concat(Object.keys(object)), [])
const union = new Set(allKeys)
if (union.size === 0) return true
if (!objects.every((object) => union.size === Object.keys(object).length)) return false
for (let key of union.keys()) {
let res = objects.map((o) => (typeof o[key] === 'object' ? o[key] : {}))
if (!objectsHaveSameKeys(...res)) return false
}
return true
}
Run Code Online (Sandbox Code Playgroud)
在我的计算机上,通过跳过concat()
并将密钥直接添加到Set()
. Schirrmacher 对原始单级版本的相同优化也实现了约 40% 的改进。
优化的深度检查现在在性能上与优化的单级版本非常相似!
function objectsHaveSameKeysOptimized(...objects) {
let union = new Set();
union = objects.reduce((keys, object) => keys.add(Object.keys(object)), union);
if (union.size === 0) return true
if (!objects.every((object) => union.size === Object.keys(object).length)) return false
for (let key of union.keys()) {
let res = objects.map((o) => (typeof o[key] === 'object' ? o[key] : {}))
if (!objectsHaveSameKeys(...res)) return false
}
return true
}
Run Code Online (Sandbox Code Playgroud)
性能比较
var x = {}
var y = {}
var a = {}
for (var j = 0; j < 10; ++j){
a[j] = j
}
for (var i = 0; i < 500000; ++i) {
x[i] = JSON.parse(JSON.stringify(a))
y[i] = JSON.parse(JSON.stringify(a))
}
let startTs = new Date()
let result = objectsHaveSameKeys(x, y)
let endTs = new Date()
console.log('objectsHaveSameKeys = ' + (endTs - startTs)/1000)
Run Code Online (Sandbox Code Playgroud)
结果
A:递归/深度检查版本*
B:原始非深度版本
归档时间: |
|
查看次数: |
72071 次 |
最近记录: |