Глубокое равенство объектов только собственных свойств объекта в Chai

У меня есть объект, который я хотел бы тщательно сравнить с другим объектом в chaijs. Проблема в том, что один объект имеет большое количество перечислимых свойств, а другой объект является простым, понятным объектом ({}).

Например, у меня есть expect(obj1).to.eql(obj2);, где obj1 — это объект со многими дополнительными перечисляемыми свойствами, добавленными библиотекой, а obj2 просто создан через var obj2 = { someValue: true }.

Эту проблему можно решить, злоупотребляя JSON.stringify и JSON.parse вот так

expect(JSON.parse(JSON.stringify(obj1))).to.eql(obj2);

но это довольно хромой хак. Я не могу себе представить, что я первый, кто столкнулся с этим затруднительным положением, но мои поиски оказались тщетными. Какой рекомендуемый подход здесь?


person mark    schedule 10.07.2015    source источник
comment
Итак, чтобы было ясно: вы хотите сравнить только собственные свойства объекта, а не свойства, добавленные в цепочку прототипов библиотекой?   -  person Hannes Johansson    schedule 10.07.2015
comment
@HannesJohansson Это абсолютно правильно. Меня просто не интересуют свойства прототипа для некоторых моих тестов.   -  person mark    schedule 10.07.2015
comment
В этом случае это не совсем перечисляемые свойства, которые вы хотите игнорировать, как сказано в заголовке вопроса, вы просто хотите игнорировать свойства, которые не являются собственными свойствами объекта.   -  person Hannes Johansson    schedule 10.07.2015


Ответы (2)


Вы можете попробовать использовать chai-shallow-deep-equal. Он не выполняет полную проверку на равенство, но проверяет, содержит ли второй объект набор свойств первого объекта.

Here's usage example:

var chai = require('chai');
chai.use(require('chai-shallow-deep-equal'));

var obj1 = {name: 'Michel', language: 'javascript'};
var obj2 = {name: 'Michel'};
var obj3 = {name: 'Michel', age: 43};

expect(obj1).to.shallowDeepEqual(obj2); // true
expect(obj1).to.shallowDeepEqual(obj3); // false, age is undefined in obj1

person edufinn    schedule 30.03.2016

Я бы предложил сделать проекцию объекта, который вы хотите протестировать, который содержит только «собственные» (не из цепочки прототипов) свойства, и сравнить их на равенство.

var projection = {};

for (var key in obj1) {
    if (obj1.hasOwnProperty(key)) {
        projection[key] = obj1[key];
    }
}

expect(projection).to.eql(obj2);

Вы можете извлечь этот проекционный код в тестовую служебную функцию.

person Hannes Johansson    schedule 10.07.2015
comment
Это достойное решение, но на самом деле оно не работает с экосистемой chai, не превращая его в плагин. например, var objs = [ obj1, obj2, obj3 ] expect(objs).to.contain(obj2); по-прежнему не работает, так как мне пришлось бы вручную перебирать все объекты и удалять их свойства прототипа (примените ваше исправление). - person mark; 10.07.2015
comment
Я не знаком с Chai, но, просматривая их API, не вижу встроенной поддержки для этого. Если вы извлечете мой код в служебную функцию, вы всегда сможете использовать его в сочетании с методом массива map для сопоставления исходного массива объектов с массивом проекций. Я не вижу более гладкого решения, извините. - person Hannes Johansson; 10.07.2015