Сравнение объектов, содержащих анонимные функции, в jest testcase

#javascript #react-native #jestjs

#javascript #react-native #jestjs

Вопрос:

Я использую jest в реактивном проекте. Я хотел бы сравнить в тестовом примере два объекта одного и того же класса. Вот пример определения класса:

 class Person {
    constructor(id, name, lastName) {
        this.id = id;
        this.name = name;
        this.lastName = lastName;
    }       

    fullName = () => {
        return `${this.name} ${this.lastName}`;
    }
}
  

Я создал тестовый пример, в котором сравнивались два объекта Person класса, которые должны быть идентичными:

 test('checks the Person.constructor method', () => {
    expect(new Person(1, 'John', 'Smith')).toEqual(new Person(1, 'John', 'Smith'));
});
  

Однако я получаю следующий результат:

  FAIL  __tests__/Comparison-test.js (7.328s)
  ● checks the Person.constructor method

    expect(received).toEqual(expected)

    Expected: {"fullName": [Function anonymous], "id": 1, "lastName": "Smith", "name": "John"}
    Received: {"fullName": [Function anonymous], "id": 1, "lastName": "Smith", "name": "John"}

      48 | 
      49 | test('checks the Person.constructor method', () => {
    > 50 |     expect(new Person(1, 'John', 'Smith')).toEqual(new Person(1, 'John', 'Smith'));
         |                                            ^
      51 | });

      at Object.toEqual (__tests__/Comparison-test.js:50:44)
  

Сравнивая ожидаемые и полученные значения, визуально я вижу, что они идентичны, однако я знаю, что они не считаются идентичными из-за анонимной функции fullName .

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

Я попытался использовать expect функцию, установив lastName значение expect.anything() . Приведенный ниже тест действительно пройден:

 test('checks the Person.constructor method', () => {
    expect(new Person(1, 'John', 'Smith')).toEqual({
        id: 1,
        name: 'John',
        lastName: 'Smith',
        fullName: expect.anything()});
});
  

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

Итак, есть ли способ сравнить два объекта одного и того же класса в jest, игнорируя все функции этих объектов?

Спасибо!

Ответ №1:

Звучит так, как будто вы хотите, toMatchObject которое соответствует «подмножеству свойств объекта»:

 test('checks the Person.constructor method', () => {
  expect(new Person(1, 'John', 'Smith')).toMatchObject({
    id: 1,
    name: 'John',
    lastName: 'Smith'
  });  // Success!
});
  

Обновить

OP спросил в комментариях, есть ли какой-либо способ по-прежнему использовать экземпляры.

Он также работает для сериализации объектов с помощью JSON.stringify и сравнения результатов:

 test('checks the Person.constructor method', () => {
  expect(JSON.stringify(new Person(1, 'John', 'Smith')))
    .toBe(JSON.stringify(new Person(1, 'John', 'Smith')));  // Success!
});
  

Комментарии:

1. Намного лучше, спасибо! Есть ли хоть какой-нибудь способ сравнить два экземпляра одного и того же класса? Вместо того, чтобы самому писать ожидаемый объект?

2. @FelipeFerri Я обновил свой ответ примером, использующим JSON.stringify