Пошук уроків, статей та іншого контенту
Навчитеся перевіряти результати тестів за допомогою базових і структурних assertions.
Assertion — це перевірка, яка порівнює фактичний результат роботи коду з очікуваним.
У тесті assertion відповідає на запитання: «Чи поводиться програма так, як ми очікуємо?»
Наприклад:
const result = 2 + 2;
const expected = 4;
// Якщо значення відрізняються, Node.js викине помилкуУ Node.js для assertions використовується вбудований модуль node:assert. Його не потрібно встановлювати окремо.
Найзручніше імпортувати строгий варіант модуля:
import assert from 'node:assert/strict';Строгий режим допомагає уникати неочікуваних перетворень типів під час порівняння.
assert.equal()assert.equal(actual, expected) перевіряє, що фактичне значення дорівнює очікуваному.
import assert from 'node:assert/strict';
const result = 2 + 2;
assert.equal(result, 4);Якщо перевірка успішна, код продовжить виконання. Якщо ні, Node.js викине AssertionError.
import assert from 'node:assert/strict';
const result = 2 + 2;
assert.equal(result, 5); // AssertionErrorУ строгому варіанті модуля assert.equal() використовує строге порівняння, аналогічне оператору ===. Тому значення різних типів не вважаються однаковими:
import assert from 'node:assert/strict';
assert.equal(5, '5'); // AssertionErrorassert.notEqual()assert.notEqual(actual, expected) перевіряє, що два значення відрізняються.
import assert from 'node:assert/strict';
const status = 'error';
assert.notEqual(status, 'success');Ця перевірка корисна, коли тест має підтвердити, що певний результат не дорівнює конкретному значенню.
assert.ok()assert.ok(value) перевіряє, що значення є істинним у JavaScript.
import assert from 'node:assert/strict';
const userName = 'Olena';
assert.ok(userName);До істинних значень належать, наприклад:
непорожній рядок;
ненульове число;
true;
об'єкт;
масив.
До хибних значень належать:
false;
0;
'';
null;
undefined;
NaN.
Приклад перевірки результату пошуку:
import assert from 'node:assert/strict';
const user = {
id: 1,
name: 'Olena',
};
assert.ok(user);За потреби можна передати третій параметр із поясненням помилки:
import assert from 'node:assert/strict';
const token = '';
assert.ok(token, 'Токен має бути непорожнім');Це повідомлення буде показане, якщо assertion не пройде.
assert.strictEqual()assert.strictEqual(actual, expected) явно виконує строге порівняння через ===.
import assert from 'node:assert/strict';
const result = 10;
assert.strictEqual(result, 10);Оскільки ми імпортували node:assert/strict, для простих значень equal() і strictEqual() поводяться однаково. strictEqual() часто використовують у коді тестів, коли хочуть явно підкреслити строге порівняння.
Порівняння об'єктів і масивів має особливість. Два окремі об'єкти з однаковими властивостями не є одним і тим самим об'єктом:
const first = { name: 'Olena' };
const second = { name: 'Olena' };
console.log(first === second); // falseОператор === порівнює посилання на об'єкти, а не їхній вміст. Для перевірки структури використовують assert.deepEqual() або assert.deepStrictEqual().
assert.deepStrictEqual()assert.deepStrictEqual(actual, expected) рекурсивно порівнює властивості об'єктів і елементи масивів.
import assert from 'node:assert/strict';
const actualUser = {
id: 1,
name: 'Olena',
};
const expectedUser = {
id: 1,
name: 'Olena',
};
assert.deepStrictEqual(actualUser, expectedUser);Також можна порівнювати масиви:
import assert from 'node:assert/strict';
const actual = ['JavaScript', 'Node.js'];
const expected = ['JavaScript', 'Node.js'];
assert.deepStrictEqual(actual, expected);Перевірка не пройде, якщо відрізняється хоча б одна властивість, значення або тип:
import assert from 'node:assert/strict';
const actual = {
id: 1,
active: true,
};
const expected = {
id: 1,
active: false,
};
assert.deepStrictEqual(actual, expected); // AssertionErrorУ більшості тестів для об'єктів і масивів варто використовувати саме deepStrictEqual, оскільки він враховує типи значень.
Іноді очікуваною поведінкою функції є не повернення результату, а викидання помилки. Для цього використовують assert.throws().
import assert from 'node:assert/strict';
function parseAge(value) {
if (typeof value !== 'number' || value < 0) {
throw new TypeError('Вік має бути невід’ємним числом');
}
return value;
}
assert.throws(
() => parseAge(-1),
TypeError,
);У першому аргументі передають функцію, яку потрібно виконати. У другому — очікуваний тип помилки.
Можна перевірити і повідомлення помилки за допомогою регулярного виразу:
import assert from 'node:assert/strict';
function parseAge(value) {
if (typeof value !== 'number' || value < 0) {
throw new TypeError('Вік має бути невід’ємним числом');
}
return value;
}
assert.throws(
() => parseAge(-1),
{
name: 'TypeError',
message: /невід’ємним числом/,
},
);Тут перевіряються:
назва помилки;
частина її повідомлення.
Розглянемо функцію, яка повертає інформацію про товар:
import assert from 'node:assert/strict';
function createProduct(name, price) {
if (!name) {
throw new Error('Назва товару є обов’язковою');
}
if (price < 0) {
throw new Error('Ціна не може бути від’ємною');
}
return {
name,
price,
available: true,
};
}
const product = createProduct('Клавіатура', 1500);
assert.ok(product);
assert.strictEqual(product.name, 'Клавіатура');
assert.strictEqual(product.price, 1500);
assert.deepStrictEqual(product, {
name: 'Клавіатура',
price: 1500,
available: true,
});
assert.throws(
() => createProduct('', 1500),
{
message: 'Назва товару є обов’язковою',
},
);
assert.throws(
() => createProduct('Клавіатура', -1),
{
message: 'Ціна не може бути від’ємною',
},
);
console.log('Усі assertions пройдено');Збережіть код у файлі assertions.mjs і запустіть:
node assertions.mjsЯкщо всі перевірки успішні, програма виведе:
Усі assertions пройденоЯкщо хоча б одна перевірка не пройде, Node.js зупинить виконання і покаже інформацію про AssertionError.
Для невдалої перевірки Node.js зазвичай показує:
тип помилки;
фактичне значення;
очікуване значення;
місце в коді, де сталася помилка.
Наприклад, для такого коду:
import assert from 'node:assert/strict';
const actual = 3;
const expected = 4;
assert.strictEqual(actual, expected);помилка означає, що фактичне значення 3 не збігається з очікуваним 4.
Це допомагає швидко знайти проблему або у функції, яку тестують, або в самому тесті.
Коли в одному тесті багато перевірок, корисно додавати опис:
import assert from 'node:assert/strict';
const user = {
role: 'admin',
};
assert.strictEqual(
user.role,
'admin',
'Користувач має мати роль admin',
);Повідомлення не змінює саму перевірку. Воно лише пояснює, що саме очікувалося у випадку помилки.
=== для об'єктівimport assert from 'node:assert/strict';
const actual = { value: 10 };
const expected = { value: 10 };
assert.strictEqual(actual, expected); // AssertionErrorОб'єкти мають однаковий вміст, але це різні об'єкти в пам'яті. Для структурного порівняння використовуйте:
assert.deepStrictEqual(actual, expected);Якщо потрібно перевірити весь об'єкт, використовуйте deepStrictEqual:
import assert from 'node:assert/strict';
const actual = {
id: 1,
name: 'Olena',
role: 'admin',
};
const expected = {
id: 1,
name: 'Olena',
};
assert.deepStrictEqual(actual, expected); // AssertionErrorВ об'єкті actual є додаткова властивість role, тому структури не збігаються.
assert.ok() для точного значенняassert.ok() перевіряє лише істинність значення:
import assert from 'node:assert/strict';
const result = 1;
assert.ok(result); // Перевірка пройдеАле ця перевірка не підтверджує, що результат дорівнює саме 1. Для точного значення використовуйте:
assert.strictEqual(result, 1);assert.throws() приймає функцію, але не результат її виклику.
Правильно:
assert.throws(() => parseAge(-1));Неправильно:
assert.throws(parseAge(-1));У неправильному варіанті функція виконається ще до того, як assert.throws() зможе її перевірити.
Assertion перевіряє відповідність фактичного результату очікуваному.
Для простих значень використовують assert.strictEqual().
Для перевірки відмінності значень використовують assert.notEqual().
assert.ok() перевіряє істинність значення.
assert.deepStrictEqual() порівнює структуру об'єктів і масивів.
assert.throws() перевіряє, що функція викидає очікувану помилку.
Додаткове повідомлення допомагає зрозуміти причину невдалої перевірки.
Для об'єктів і масивів не слід використовувати ===, якщо потрібно порівняти їхній вміст.