Серия синтаксиса тестов Jest — Ожидайте
Серия синтаксиса тестов Jest — Ожидайте

Methods

Expect в основном используется для реализации операций проверки. Expect Jest предоставляет следующие методы проверки:

  • expect(value)
  • expect.extend(matchers)
  • expect.anything()
  • expect.any(constructor)
  • expect.arrayContaining(array)
  • expect.assertions(number)
  • expect.hasAssertions()
  • expect.not.arrayContaining(array)
  • expect.not.objectContaining(object)
  • expect.not.stringContaining(string)
  • expect.not.stringMatching(string | regexp)
  • expect.objectContaining(object)
  • expect.stringContaining(string)
  • expect.stringMatching(string | regexp)
  • expect.addSnapshotSerializer(serializer)
  • .not
  • .resolves
  • .rejects
  • .toBe(value)
  • .toHaveBeenCalled()
  • .toHaveBeenCalledTimes(number)
  • .toHaveBeenCalledWith(arg1, arg2, …)
  • .toHaveBeenLastCalledWith(arg1, arg2, …)
  • .toHaveBeenNthCalledWith(nthCall, arg1, arg2, …)
  • .toHaveReturned()
  • .toHaveReturnedTimes(number)
  • .toHaveReturnedWith(value)
  • .toHaveLastReturnedWith(value)
  • .toHaveNthReturnedWith(nthCall, value)
  • .toBeCloseTo(number, numDigits)
  • .toBeDefined()
  • .toBeFalsy()
  • .toBeGreaterThan(number)
  • .toBeGreaterThanOrEqual(number)
  • .toBeLessThan(number)
  • .toBeLessThanOrEqual(number)
  • .toBeInstanceOf(Class)
  • .toBeNull()
  • .toBeTruthy()
  • .toBeUndefined()
  • .toContain(item)
  • .toContainEqual(item)
  • .toEqual(value)
  • .toHaveLength(number)
  • .toMatch(regexpOrString)
  • .toMatchObject(object)
  • .toHaveProperty(keyPath, value)
  • .toMatchSnapshot(propertyMatchers, snapshotName)
  • .toMatchInlineSnapshot(propertyMatchers, inlineSnapshot)
  • .toStrictEqual(value)
  • .toThrow(error)
  • .toThrowErrorMatchingSnapshot()
  • .toThrowErrorMatchingInlineSnapshot()

Reference

expect(value)

Вы используете функцию «ожидание» всякий раз, когда хотите проверить значение. Вероятно, вы редко будете вызывать функцию «ожидание». Вместо этого вы будете использовать функцию «ожидание» и «сопоставитель», чтобы утверждать что-то о значении. Для облегчения понимания мы предполагаем, что у вас есть метод bestLaCroixFlavor(), ожидаемый результат которого:

Язык кода:javascript
копировать
test('the best flavor is grapefruit', () => {
  expect(bestLaCroixFlavor()).toBe('grapefruit');
});

В приведенном выше примере toBe — это функция сопоставления. Чтобы помочь вам протестировать различный контент, Jest предоставляет множество различных функций сопоставления. Аргументы Expect должны быть значениями, сгенерированными кодом, а любые аргументы соответствующей программы должны быть правильными значениями.

expect.extend(matchers)

Вы можете добавить свои собственные средства сопоставления в Jest, используя ожидаемое.extend. Например, предположим, что вы тестируете теоретическую библиотеку и часто утверждаете, что числа делятся на другие числа, вы можете абстрагировать это в сопоставитель toBeDivisibleBy.

Язык кода:javascript
копировать
expect.extend({
  toBeDivisibleBy(received, argument) {
    const pass = received % argument == 0;
    if (pass) {
      return {
        message: () =>
          `expected ${received} not to be divisible by ${argument}`,
        pass: true,
      };
    } else {
      return {
        message: () => `expected ${received} to be divisible by ${argument}`,
        pass: false,
      };
    }
  },
});
 
test('even and odd numbers', () => {
  expect(100).toBeDivisibleBy(2);
  expect(101).not.toBeDivisibleBy(2);
  expect({apples: 6, bananas: 3}).toEqual({
    apples: expect.toBeDivisibleBy(2),
    bananas: expect.not.toBeDivisibleBy(2),
  });
});

ожидаемое.extends также поддерживает асинхронные сопоставления, которые возвращают обещание, поэтому вам нужно дождаться возвращенного значения. Давайте воспользуемся примером сопоставления, чтобы проиллюстрировать их использование. Вместо toBeDivisibleBy мы собираемся реализовать очень похожий механизм сопоставления, с той лишь разницей, что делимые числа будут извлекаться из внешнего источника.

Язык кода:javascript
копировать
expect.extend({
  async toBeDivisibleByExternalValue(received) {
    const externalValue = await getExternalValueFromRemoteSource();
    const pass = received % externalValue == 0;
    if (pass) {
      return {
        message: () =>
          `expected ${received} not to be divisible by ${externalValue}`,
        pass: true,
      };
    } else {
      return {
        message: () =>
          `expected ${received} to be divisible by ${externalValue}`,
        pass: false,
      };
    }
  },
});
 
test('is divisible by external value', async () => {
  await expect(100).toBeDivisibleByExternalValue();
  await expect(101).not.toBeDivisibleByExternalValue();
});

Сопоставитель должен возвращать объект (или обещание объекта) с обоими ключами. pass указывает, есть ли совпадение, а message предоставляет функцию без параметров, которая возвращает сообщение об ошибке в случае сбоя. Поэтому, если pass имеет значение false, сообщение должно возвращать сообщение об ошибке в случае сбоя ожидаемого(x).yourmatcher(). Если pass истинен, сообщение должно возвращать ожидаемое(x).no Сообщение об ошибке при сбое yourmatcher().

this.equals(a, b)

Возвращает true, если два объекта имеют одинаковое значение (рекурсивно). this.utils содержит много полезных инструментов, utils в основном состоит из экспорта из jest-matcher-utils. Наиболее полезными из них являются matcherHint, printExpected и printReceived, которые хорошо форматируют сообщения об ошибках.

Язык кода:javascript
копировать
const diff = require('jest-diff');
expect.extend({
  toBe(received, expected) {
    const pass = Object.is(received, expected);
 
    const message = pass
      ? () =>
          this.utils.matcherHint('.not.toBe') +
          '\n\n' +
          `Expected value to not be (using Object.is):\n` +
          `  ${this.utils.printExpected(expected)}\n` +
          `Received:\n` +
          `  ${this.utils.printReceived(received)}`
      : () => {
          const diffString = diff(expected, received, {
            expand: this.expand,
          });
          return (
            this.utils.matcherHint('.toBe') +
            '\n\n' +
            `Expected value to be (using Object.is):\n` +
            `  ${this.utils.printExpected(expected)}\n` +
            `Received:\n` +
            `  ${this.utils.printReceived(received)}` +
            (diffString ? `\n\nDifference:\n\n${diffString}` : '')
          );
        };
 
    return {actual: received, message, pass};
  },
}); 

Выполнение приведенного выше кода приведет к появлению следующего сообщения об ошибке:

Язык кода:javascript
копировать
expect(received).toBe(expected)
 
   Expected value to be (using Object.is):
     "banana"
   Received:
     "apple"

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

expect.anything()

Он соответствует чему угодно, кроме null или неопределенного. Вы можете использовать toEqual или toBeCalledWith вместо литеральных значений. Например, если вы хотите проверить, была ли вызвана фиктивная функция и ее аргументы были ненулевыми:

Язык кода:javascript
копировать
test('map calls its argument with a non-null argument', () => {
  const mock = jest.fn();
  [1].map(x => mock(x));
  expect(mock).toBeCalledWith(expect.anything());
});

expect.any(constructor)

Соответствует всему, что создано данным конструктором. Вы можете использовать toEqual или toBeCalledWith вместо литеральных значений. Например, если вы хотите проверить, была ли вызвана фиктивная функция с номером.

Язык кода:javascript
копировать
function randocall(fn) {
  return fn(Math.floor(Math.random() * 6 + 1));
}
 
test('randocall calls its callback with a number', () => {
  const mock = jest.fn();
  randocall(mock);
  expect(mock).toBeCalledWith(expect.any(Number));
});

expect.arrayContaining(array)

Соответствует полученному массиву, содержащему все элементы ожидаемого массива, т. е. ожидаемый массив является подмножеством полученного массива, поэтому он соответствует полученному массиву, содержащему элементы, не являющиеся частью ожидаемого массива.

Язык кода:javascript
копировать
describe('arrayContaining', () => {
  const expected = ['Alice', 'Bob'];
  it('matches even if received contains additional elements', () => {
    expect(['Alice', 'Bob', 'Eve']).toEqual(expect.arrayContaining(expected));
  });
  it('does not match if received does not contain expected elements', () => {
    expect(['Bob', 'Eve']).not.toEqual(expect.arrayContaining(expected));
  });
});
Язык кода:javascript
копировать
describe('Beware of a misunderstanding! A sequence of dice rolls', () => {
  const expected = [1, 2, 3, 4, 5, 6];
  it('matches even with an unexpected number 7', () => {
    expect([4, 1, 6, 7, 3, 5, 2, 5, 4, 6]).toEqual(
      expect.arrayContaining(expected)
    );
  });
  it('does not match without an expected number 2', () => {
    expect([4, 1, 6, 7, 3, 5, 7, 5, 4, 6]).not.toEqual(
      expect.arrayContaining(expected),
    );
  });
});

expect.assertions(number)

Проверяет, что во время теста вызывается определенное количество утверждений. Это часто бывает полезно при тестировании асинхронного кода, чтобы гарантировать, что утверждения в обратных вызовах действительно вызываются. Предположим, у нас есть функция doAsync, которая получает два обратных вызова callback1 и callback2 и вызывает их асинхронно в неизвестном порядке.

Язык кода:javascript
копировать
test('doAsync calls both callbacks', () => {
  expect.assertions(2);
  function callback1(data) {
    expect(data).toBeTruthy();
  }
  function callback2(data) {
    expect(data).toBeTruthy();
  }
 
  doAsync(callback1, callback2);
});

expect.hasAssertions()

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

Предположим, у нас есть некоторые функции, которые обрабатывают состояние: «prepreState» вызывает обратный вызов для объекта состояния, validateState выполняется для этого объекта состояния, а waitOnState возвращает обещание до тех пор, пока все обратные вызовы «prepreState» не будут завершены.

Язык кода:javascript
копировать
test('prepareState prepares a valid state', () => {
  expect.hasAssertions();
  prepareState(state => {
    expect(validateState(state)).toBeTruthy();
  });
  return waitOnState();
});

expect.not.arrayContaining(array)

Соответствует полученному массиву, который не содержит элементов ожидаемого массива. То есть ожидаемый массив не является подмножеством полученного массива, что противоположно ожидаемому.arrayContaining.

Язык кода:javascript
копировать
describe('not.arrayContaining', () => {
  const expected = ['Samantha'];
 
  it('matches if the actual array does not contain the expected elements', () => {
    expect(['Alice', 'Bob', 'Eve']).toEqual(
      expect.not.arrayContaining(expected),
    );
  });
});

expect.not.objectContaining(object)

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

Язык кода:javascript
копировать
describe('not.objectContaining', () => {
  const expected = {foo: 'bar'};
 
  it('matches if the actual object does not contain expected key: value pairs', () => {
    expect({bar: 'baz'}).toEqual(expect.not.objectContaining(expected));
  });
});

expect.not.stringContaining(string)

Соответствует полученной строке, которая не содержит точной ожидаемой строки, что противоположно ожидаемому.stringContaining.

Язык кода:javascript
копировать
describe('not.stringContaining', () => {
  const expected = 'Hello world!';
 
  it('matches if the actual string does not contain the expected substring', () => {
    expect('How are you?').toEqual(expect.not.stringContaining(expected));
  });
});

expect.not.stringMatching(string | regexp)

Соответствует полученной строке, которая не соответствует ожидаемому регулярному выражению, что противоположно ожидаемому.stringMatching.

Язык кода:javascript
копировать
describe('not.stringMatching', () => {
  const expected = /Hello world!/;
 
  it('matches if the actual string does not match the expected regex', () => {
    expect('How are you?').toEqual(expect.not.stringMatching(expected));
  });
});

expect.objectContaining(object)

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

Вместо того, чтобы ожидать в объектах буквальных значений свойств, вы можете использовать сопоставители, ожидаемые.anything() и так далее. Предположим, мы хотим использовать объект события для вызова функции onPress. Нам нужно проверить, имеет ли событие атрибуты event.x и атрибуты y.

Язык кода:javascript
копировать
test('onPress gets called with the right thing', () => {
  const onPress = jest.fn();
  simulatePresses(onPress);
  expect(onPress).toBeCalledWith(
    expect.objectContaining({
      x: expect.any(Number),
      y: expect.any(Number),
    }),
  );
});

expect.stringMatching(string | regexp)

Соответствует полученной строке, соответствующей ожидаемому регулярному выражению, которое можно использовать вместо буквального значения:

  1. в toEqual или toBeCalledWith
  2. Сопоставить элементы в arraycontains
  3. Сопоставление свойств objectContaining или toMatchObject.
Язык кода:javascript
копировать
describe('stringMatching in arrayContaining', () => {
  const expected = [
    expect.stringMatching(/^Alic/),
    expect.stringMatching(/^[BR]ob/),
  ];
  it('matches even if received contains additional elements', () => {
    expect(['Alicia', 'Roberto', 'Evelina']).toEqual(
      expect.arrayContaining(expected),
    );
  });
  it('does not match if received does not contain expected elements', () => {
    expect(['Roberto', 'Evelina']).not.toEqual(
      expect.arrayContaining(expected),
    );
  });
});

.toBe(value)

toBe просто проверяет, соответствует ли значение вашим ожиданиям. Если он использует объект, он проверяет точное равенство.

Язык кода:javascript
копировать
const can = {
  name: 'pamplemousse',
  ounces: 12,
};
 
describe('the can', () => {
  test('has 12 ounces', () => {
    expect(can.ounces).toBe(12);
  });
 
  test('has a sophisticated name', () => {
    expect(can.name).toBe('pamplemousse');
  });
});

.toEqual(value)

Если вы хотите проверить, имеют ли два объекта одинаковое значение, используйте .toequal. Этот сопоставитель рекурсивно проверяет все поля на равенство вместо проверки идентификаторов объектов — это также называется «глубоким равенством». Например, toEqual и toBe ведут себя в этом наборе тестов по-разному, поэтому все тесты проходят успешно.

Язык кода:javascript
копировать
const can1 = {
  flavor: 'grapefruit',
  ounces: 12,
};
const can2 = {
  flavor: 'grapefruit',
  ounces: 12,
};
 
describe('the La Croix cans on my desk', () => {
  test('have all the same properties', () => {
    expect(can1).toEqual(can2);
  });
  test('are not the exact same can', () => {
    expect(can1).not.toBe(can2);
  });
});

.toMatchObject(object)

Используйте .tomatobject, чтобы проверить, соответствует ли объект JavaScript подмножеству свойств объекта. Он сопоставит полученный объект со свойствами, которых нет в ожидаемом объекте.

Вы также можете передать массив объектов, и в этом случае метод будет работать только в том случае, если каждый объект в полученном массиве (в смысле объекта Tomato, описанном выше) соответствует соответствующему объекту в ожидаемом массиве. Возврат true. Это полезно, если вы хотите проверить совпадение двух массивов по количеству элементов, вместо arrayinclude, поскольку позволяет добавлять дополнительные элементы в полученный массив.

Язык кода:javascript
копировать
const houseForSale = {
  bath: true,
  bedrooms: 4,
  kitchen: {
    amenities: ['oven', 'stove', 'washer'],
    area: 20,
    wallColor: 'white',
  },
};
const desiredHouse = {
  bath: true,
  kitchen: {
    amenities: ['oven', 'stove', 'washer'],
    wallColor: expect.stringMatching(/white|yellow/),
  },
};
 
test('the house has my desired features', () => {
  expect(houseForSale).toMatchObject(desiredHouse);
});
Язык кода:javascript
копировать
describe('toMatchObject applied to arrays arrays', () => {
  test('the number of elements must match exactly', () => {
    expect([{foo: 'bar'}, {baz: 1}]).toMatchObject([{foo: 'bar'}, {baz: 1}]);
  });
 
  // .arrayContaining "matches a received array which contains elements that
  // are *not* in the expected array"
  test('.toMatchObject does not allow extra elements', () => {
    expect([{foo: 'bar'}, {baz: 1}]).toMatchObject([{foo: 'bar'}]);
  });
 
  test('.toMatchObject is called for each elements, so extra object properties are okay', () => {
    expect([{foo: 'bar'}, {baz: 1, extra: 'quux'}]).toMatchObject([
      {foo: 'bar'},
      {baz: 1},
    ]);
  });
});

.toHaveProperty(keyPath ,value)

Используйте .tohaveproperty, чтобы проверить, существует ли свойство объекта в указанном ссылочном ключевом пути. Чтобы проверить глубоко вложенные свойства объекта, вы можете использовать точечную запись или массив, содержащий ключевой путь с глубокой ссылкой.

При желании вы можете указать значение, чтобы проверить, равно ли оно значению в keyPath целевого объекта. Этот сопоставитель использует «глубокое равенство» (например, toEqual()) и рекурсивно проверяет все поля на равенство.

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

Язык кода:javascript
копировать
const houseForSale = {
  bath: true,
  bedrooms: 4,
  kitchen: {
    amenities: ['oven', 'stove', 'washer'],
    area: 20,
    wallColor: 'white',
    'nice.oven': true,
  },
};
 
test('this house has my desired features', () => {
  // Simple Referencing
  expect(houseForSale).toHaveProperty('bath');
  expect(houseForSale).toHaveProperty('bedrooms', 4);
 
  expect(houseForSale).not.toHaveProperty('pool');
 
  // Deep referencing using dot notation
  expect(houseForSale).toHaveProperty('kitchen.area', 20);
  expect(houseForSale).toHaveProperty('kitchen.amenities', [
    'oven',
    'stove',
    'washer',
  ]);
 
  expect(houseForSale).not.toHaveProperty('kitchen.open');
 
  // Deep referencing using an array containing the keyPath
  expect(houseForSale).toHaveProperty(['kitchen', 'area'], 20);
  expect(houseForSale).toHaveProperty(
    ['kitchen', 'amenities'],
    ['oven', 'stove', 'washer'],
  );
  expect(houseForSale).toHaveProperty(['kitchen', 'amenities', 0], 'oven');
  expect(houseForSale).toHaveProperty(['kitchen', 'nice.oven']);
  expect(houseForSale).not.toHaveProperty(['kitchen', 'open']);
});

другой: Модульное фронтенд-тестирование Jest Фермент, среда тестирования React Серия синтаксисов тестов Globals of Jest Серия синтаксиса тестов Jest — Matchers

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose