Object matchers

Jasmine предоставляет мощный инструментарий для тестирования объектов в JavaScript, включая специальные object matchers, которые позволяют проверять свойства, структуру и значения объектов с высокой точностью. В тестировании объектов важны два аспекта: структура объекта и значения его свойств, и Jasmine предлагает гибкие методы для проверки обоих.


Проверка строгого равенства объектов — toEqual

Метод toEqual сравнивает объекты по значению всех их свойств, а не по ссылке. Это основной способ убедиться, что объект соответствует ожидаемой структуре и содержимому.

describe("Пример использования toEqual", () => {
  it("сравнивает объекты по содержимому", () => {
    const obj = { name: "Alice", age: 25 };
    expect(obj).toEqual({ name: "Alice", age: 25 });
  });
});

Особенности toEqual:

  • Сравниваются вложенные объекты и массивы рекурсивно.
  • Функции в объектах сравниваются по ссылке, а не по содержимому.
  • Для проверки типов и значений одновременно подходит только строгая структура объекта.

Проверка наличия свойств — toHaveProperty

Для случаев, когда важна наличие свойства, но не обязательно проверка всех остальных данных, используют toHaveProperty. Jasmine поддерживает эту проверку через сочетание кастомных матчеров или через проверку конкретного свойства объекта.

describe("Проверка свойств объекта", () => {
  it("объект содержит свойство name", () => {
    const obj = { name: "Bob", age: 30 };
    expect(obj.name).toBeDefined();
  });
});

Ключевые моменты:

  • Можно проверять глубокие свойства через цепочку точек.
  • Метод toBeDefined() часто используется для проверки существования свойства.

Гибкая проверка структуры — jasmine.objectContaining

Для проверки части объекта, когда неважны все свойства, используют jasmine.objectContaining. Этот matcher позволяет убедиться, что объект содержит заданные ключи с ожидаемыми значениями, игнорируя остальные.

describe("Использование jasmine.objectContaining", () => {
  it("проверяет только часть объекта", () => {
    const user = { name: "Carol", age: 28, role: "admin" };
    expect(user).toEqual(jasmine.objectContaining({ name: "Carol", age: 28 }));
  });
});

Особенности objectContaining:

  • Позволяет фокусироваться на ключевых свойствах, не привязываясь к полной структуре.
  • Отлично подходит для проверки объектов с динамическими или дополнительными свойствами.
  • Может использоваться в комбинации с другими матчерами для сложных проверок.

Сравнение массивов объектов — arrayContaining и arrayWithExactContents

Jasmine предоставляет специальные матчера для работы с массивами объектов:

  • jasmine.arrayContaining(array) проверяет, что массив содержит все указанные элементы, но может содержать и другие.
  • jasmine.arrayWithExactContents(array) требует точного совпадения элементов, порядок не важен.
describe("Проверка массивов объектов", () => {
  it("массив содержит объект с заданными свойствами", () => {
    const users = [
      { name: "Alice", age: 25 },
      { name: "Bob", age: 30 }
    ];
    expect(users).toEqual(jasmine.arrayContaining([{ name: "Alice", age: 25 }]));
  });
});

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


Комбинация с другими матчерами

Object matchers можно комбинировать с другими Jasmine матчерами для проверки типов и условий:

  • jasmine.any(Constructor) проверяет тип значения объекта.
  • jasmine.anything() допускает любое значение, кроме null и undefined.
  • jasmine.objectContaining({...}) можно вложить внутри массивов или других объектов.

Пример:

describe("Комбинация матчеров", () => {
  it("объект с конкретными типами свойств", () => {
    const person = { name: "David", age: 40, address: { city: "Moscow" } };
    expect(person).toEqual(jasmine.objectContaining({
      name: jasmine.any(String),
      age: jasmine.any(Number),
      address: jasmine.objectContaining({
        city: "Moscow"
      })
    }));
  });
});

Глубокая проверка и вложенные объекты

Object matchers особенно полезны для сложных объектов с вложенной структурой. Для тестирования таких объектов важно:

  1. Проверять ключевые свойства на существование.
  2. Проверять значения через toEqual или objectContaining.
  3. Использовать jasmine.any() для гибкой проверки типов вложенных свойств.
describe("Вложенные объекты", () => {
  it("проверяет вложенные структуры", () => {
    const data = {
      user: {
        name: "Eve",
        contact: { email: "eve@example.com", phone: null }
      }
    };
    expect(data).toEqual(jasmine.objectContaining({
      user: jasmine.objectContaining({
        name: "Eve",
        contact: jasmine.objectContaining({
          email: jasmine.any(String)
        })
      })
    }));
  });
});

Использование кастомных функций для сложной проверки

Если стандартных матчеров недостаточно, можно использовать функцию внутри expect с jasmine.anything() или простыми проверками через toBeTrue(), toBeFalsy() и пользовательские условия.

describe("Кастомная проверка объектов", () => {
  it("валидирует объект с условием", () => {
    const obj = { value: 15 };
    expect(obj.value > 10).toBeTrue();
  });
});

Такой подход позволяет комбинировать строгие проверки структуры с логическими условиями для значений.


Object matchers в Jasmine обеспечивают гибкость и точность при тестировании объектов любой сложности, от простых ключ-значение до вложенных структур и массивов объектов. Правильное сочетание toEqual, objectContaining, arrayContaining и типовых матчеров позволяет создавать тесты, которые проверяют не только наличие данных, но и их соответствие ожиданиям по типу и структуре.