Вариант toEqual, который работает со свойствами класса так же, как он работает с методами класса - PullRequest
1 голос
/ 09 апреля 2019

Это сценарий. Первый класс имеет метод 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,
  };
}

1 Ответ

1 голос
/ 09 апреля 2019

Проблема в том, что свойства класса функций создаются для каждого экземпляра ...

... поэтому 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!
...