Это сценарий. У первого класса есть метод getName
, а у второго класса есть свойство класса getName
. Первый класс работает с toEqual
, а второй нет.
class Person01 {
constructor(name) { this.name = name; }
getName() { return this.name; }
}
class Person02 {
constructor(name) { this.name = name; }
getName = () => { return this.name; }
}
const testCases = [
[
// passes
new Person01('Alan', 'Kay'),
new Person01('Alan', 'Kay'),
],
[
// fails due to class properties
new Person02('Alan', 'Kay'),
new Person02('Alan', 'Kay'),
]
];
describe('when one class has the same values that another class has', () =>
testCases.forEach(pair =>
it('is considered to be equal to that class', () =>
expect(pair[0]).toEqual(pair[1]))));
Это сообщение об ошибке для второго класса.
Expected: {"firstName": "Alan", "getName": [Function anonymous], "lastName": "Kay"}
Received: {"firstName": "Alan", "getName": [Function anonymous], "lastName": "Kay"}
Наш текущий обходной путь — запустить JSON.parse(JSON.stringify(obj))
на фактических и ожидаемых значениях.
Вместо этого мы ищем вариант toEqual
, который работает так же со свойствами класса, как и с методами класса.
Вот наш файл babel.config.js.
module.exports = function (api) {
api.env();
const plugins = [
"@babel/proposal-class-properties",
];
return {
plugins,
};
}
Проблема в том, что свойства класса функций создаются для каждого экземпляра...
... поэтому toEqual
терпит неудачу, поскольку каждый экземпляр имеет другой набор свойств функции.
Один из вариантов — создать пользовательский сопоставитель, но это сложно, поскольку toEqual
много делает.
Другой вариант — просто отфильтровать свойства функции перед использованием toEqual
:
const filterFunctions = (obj) =>
Object.keys(obj)
.filter(k => typeof obj[k] !== 'function')
.reduce((a, k) => { a[k] = obj[k]; return a; }, {});
describe('when one class has the same values that another class has', () =>
testCases.forEach(pair =>
it('is considered to be equal to that class', () =>
expect(filterFunctions(pair[0])).toEqual(filterFunctions(pair[1]))))); // Success!
Кроме того, для полного ответа требуется рекурсивный шаг для фильтрации функций во вложенных объектах.
Одна трудность здесь заключается в том, что
filterFunctions
также фильтрует методы.