toBe vs toEqual в Jasmine: различия при тестировании чисел
Быстрый ответ
Матчер toBe
применяется для проверки строгого равенства объектов — они должны быть не просто эквивалентны, но также указывать на одну и ту же область в памяти. Это аналог операции ===
в JavaScript. Матчер toEqual
соответственно служит для сопоставления объектов путем сравнения их содержимого. Он незаменим при сравнении структуры объектов.
Примеры использования:
expect(1).toBe(1); // Верно, поскольку число идентично самому себе.
expect({ a: 1 }).toBe({ a: 1 }); // Неверно, свойства идентичны, но это разные объекты.
expect({ a: 1 }).toEqual({ a: 1 }); // Верно, содержимое объектов совпадает, и для Jasmine это норма.
Понимание разницы между toBe
и toEqual
позволит вам эффективно проводить тестирование кода на JavaScript.
Что скрывается внутри – toBe
против toEqual
toBe
— это матчер для проверки строгого соответствия, который использует для сравнения операцию ===
. Это делает его оптимальным выбором для сравнения примитивных типов данных, требующих точного совпадения. Однако следует помнить, что даже два навне идентичных объекта не будут считаться равными:
const bobby = {};
const bobbyClone = {};
expect(bobby).toBe(bobbyClone); // Неверно, ведь это разные объекты, хоть и выглядят одинаково.
В это время toEqual
проводит основательное сравнение, анализируя каждое свойство и его потомков на предмет равенства:
const bobby = { child: { toy: 'Резиновая уточка' } };
const bobbyClone = { child: { toy: 'Резиновая уточка' } };
expect(bobby).toEqual(bobbyClone); // Верно, поскольку структура и содержимое объектов идентичны.
toEqual
также невероятно полезен при работе с такими объектами JavaScript, как Date
, RegExp
и обёртки чисел, благодаря своему акценту на значении, а не на конкретной реализации объекта.
Особые сценарии
Числовые сравнения: подсчёт дохода
При числовых сравнениях важно выбрать правильный матчер, чтобы избежать тонких ошибок. Рассмотрим пример банкира:
const vaultGoldBarsString = "100";
const vaultGoldBarsNumber = 100;
expect(+vaultGoldBarsString).toBe(vaultGoldBarsNumber); // Верно, поскольку строка была преобразована в число.
expect(vaultGoldBarsString).not.toEqual(vaultGoldBarsNumber); // Также верно, так как сравниваются разные типы данных.
Сравнение ссылок на объекты: двойники
Если у вас есть функция, возвращающая объект-синглтон, она должна всегда возвращать один и тот же экземпляр:
const singleton = {};
function getSingleton() { return singleton; }
expect(getSingleton()).toBe(singleton); // Верно, поскольку возвращается тот же самый объект.
Массивы и сложные объекты: зеркальный лабиринт
При работе с массивами или сложными объектами toEqual
становится наилучшим помощником:
const swanLakeBallet = [1, 2, 3];
const swanLakeBalletRehearsal = [1, 2, 3];
expect(swanLakeBallet).toEqual(swanLakeBalletRehearsal); // Верно, массивы идентичны по содержимому.
Специальные объекты JavaScript: путешественники во времени и строки
toEqual
эффективно справляется с сравнением специальных объектов JavaScript:
expect(new Date('2023-01-01')).toEqual(new Date('2023-01-01')); // Верно, временные отметки совпадают.
expect(new RegExp('ab+c')).toEqual(/ab+c/); // Верно, регулярные выражения идентичны.
Ловушки на пути
Осторожно: числа с плавающей точкой
При работе с числами с плавающей точкой необходимо учесть их особенности:
expect(0.1 + 0.2).toBe(0.3); // Неверно из-за ошибки округления.
expect(0.1 + 0.2).toBeCloseTo(0.3, 5); // Верно, благодаря использованию округления.
Изменяемые объекты: будьте осторожны с ошибками
С матчером toBe
могут возникнуть сюрпризы при работе с изменяемыми объектами:
const originalOrder = [1, 2, 3];
const messedUpOrder = originalOrder;
messedUpOrder.push(4);
expect(messedUpOrder).toBe(originalOrder); // Верно, невзирая на изменения в одном из объектов.
Тщательность выбора: значения, созданные через конструкторы
Не рекомендуется применять toBe
для сравнения объектов, созданных с использованием new
:
expect(new String('привет')).toBe('привет'); // Неверно, поскольку это разные реализации одной и той же строки.
Визуализация
Можно провести аналогию между toBe
и toEqual
и трудом двух детективов:
Детектив toBe
сосредоточен на строгой идентичности:
🕵️♂️ "Мне нужен точный двойник!"
// Две сущности с идентичными ссылками подвергаются сравнению.
Детектив toEqual
ищет идентичность в содержимом:
🕵️♀️ "Это ваш близнец?"
// Две сущности, похожие внешне и по содержанию, подвергаются сравнению, но они не обязательно должны быть одним и тем же.
Похоже, осознание их особенностей — ключ к успешному тестированию. 🕵️♂️🔍🕵️♀️
Глубокое погружение в секретные архивы Jasmine
Для лучшего понимания работы матчеров Jasmine рекомендуется просмотреть их исходный код на GitHub. Изучение принципа работы строгого сравнения toBe
и глубокого сравнения toEqual
повысит вашу грамотность в области тестирования с Jasmine.
Ключевые уроки для дальнейшего совершенствования
Изучайте документацию Jasmine, проходите онлайн-курсы и принимайте участие в обсуждениях на страницах вики Jasmine на GitHub, чтобы продолжить развивать свои навыки тестирования.
Полезные материалы
- Документация Jasmine: начало работы с матчерами — официальное руководство по использованию матчеров в Jasmine.
- Сравнение toBe и toEqual в Jasmine на Stack Overflow — обсуждение тонкостей использования матчеров среди профессионалов.
- Матчеры Jasmine и тестирование JavaScript – обучающее видео — видеогид, демонстрирующий применение Jasmine на практике.
- Тонкости работы матчеров toBe и toEqual в Jasmine – Wiki на GitHub — обширный источник знаний и подробной документации от сообщества разработчиков.
- Руководство по созданию собственных матчеров равенства в Jasmine — глубокое погружение в настройку проверки равенства объектов с помощью Jasmine.