Цепочки матчеров с not

В Jasmine ключевым элементом для проверки значений являются матчеры — функции, позволяющие сравнивать ожидаемый результат с реальным. Иногда необходимо не только проверять соответствие определённым условиям, но и обратное соответствие. Для этого используется ключевое слово not, которое позволяет инвертировать поведение матчеров.


Основная концепция not

not применяется непосредственно перед матчером и изменяет его смысл на противоположный. Структура записи выглядит так:

expect(actual).not.matcher(expected);
  • actual — значение, которое проверяется.
  • matcher — функция-сравнитель (например, toBe, toEqual).
  • expected — ожидаемое значение.

Использование not позволяет писать проверки типа:

expect(5).not.toBe(10); // Проверка, что 5 не равно 10
expect([1, 2]).not.toEqual([3, 4]); // Проверка, что массивы не равны

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


Примеры с основными матчерами

  1. toBe

Проверяет строгую равенство (===):

expect(true).not.toBe(false);
expect("hello").not.toBe("world");
  1. toEqual

Сравнивает содержимое объектов или массивов:

const user = { name: "Alice", age: 25 };
expect(user).not.toEqual({ name: "Bob", age: 25 });

const arr = [1, 2, 3];
expect(arr).not.toEqual([4, 5, 6]);
  1. toContain

Проверяет наличие элемента в массиве или подстроки в строке:

const fruits = ["apple", "banana"];
expect(fruits).not.toContain("orange");

const str = "JavaScript";
expect(str).not.toContain("Python");
  1. toBeTruthy / toBeFalsy

Позволяет проверить логическое значение:

expect(false).not.toBeTruthy();
expect(1).not.toBeFalsy();

Цепочки матчеров

В Jasmine матчеры можно комбинировать цепочками. При этом not может стоять в начале цепочки, влияя на весь матчинг. Пример использования:

expect([1, 2, 3]).not.toContain(4);
expect("OpenAI").not.toMatch(/Closed/);
expect(10).not.toBeLessThan(5);

Особенности работы:

  • not применяется к следующему матчеру, и нельзя инвертировать весь блок ожиданий сразу.
  • Цепочки можно строить, комбинируя разные матчеры, но каждое not действует локально:
expect(7).not.toBeGreaterThan(10); // корректно
expect(7).not.toBeGreaterThan(5).toBeLessThan(10); 
// первое условие инвертировано, второе выполняется как обычная проверка

Использование not с кастомными матчерами

Jasmine позволяет создавать пользовательские матчеры, и not можно применять к ним так же, как к встроенным:

beforeEach(() => {
  jasmine.addMatchers({
    toBeDivisibleBy: () => ({
      compare: (actual, expected) => ({
        pass: actual % expected === 0,
        message: `${actual} не делится на ${expected}`
      })
    })
  });
});

it("проверка кастомного матчера с not", () => {
  expect(7).not.toBeDivisibleBy(3); // 7 не делится на 3
});

Рекомендации по использованию

  • Применять not следует только тогда, когда действительно нужна обратная проверка.
  • Сложные условия лучше разбивать на несколько expect, чтобы каждая проверка была читабельной и предсказуемой.
  • В цепочках матчеров с not важно помнить локальный эффект — каждая инверсия касается только одного матчера.
  • Для массивов и объектов предпочтительно использовать toContain, toEqual или кастомные матчеры, так как toBe проверяет только ссылочную идентичность.

Практические примеры

  1. Проверка, что массив не содержит определённое значение:
const numbers = [10, 20, 30];
expect(numbers).not.toContain(40);
  1. Проверка строки на отсутствие подстроки:
const phrase = "Testing Jasmine";
expect(phrase).not.toMatch(/Cucumber/);
  1. Проверка объектов на отсутствие совпадения с другим объектом:
const person = { name: "John", age: 30 };
expect(person).not.toEqual({ name: "Jane", age: 30 });
  1. Проверка с кастомным матчером и not:
expect(15).not.toBeDivisibleBy(4);
expect(18).not.toBeDivisibleBy(7);

Цепочки матчеров с not позволяют создавать гибкие и выразительные тесты, инвертируя поведение стандартных проверок и повышая читаемость кода. Правильное использование not делает тесты более наглядными и позволяет однозначно выражать условия отсутствия или несоответствия.