Cara Menggunakan Assert di Node.js: Panduan Praktis

INEZA Felin-Michel

INEZA Felin-Michel

22 May 2026

Cara Menggunakan Assert di Node.js: Panduan Praktis

Apidog untuk Perusahaan

Penerapan On-Premises

SSO & RBAC

Sesuai SOC 2

Jelajahi Apidog Enterprise

Setiap kerangka kerja pengujian yang pernah Anda gunakan, baik Jest, Mocha, atau node:test, didasarkan pada ide sederhana: nyatakan apa yang Anda harapkan, lalu lemparkan galat jika kenyataan tidak sesuai. Node.js menyertakan ide itu sebagai modul bawaan bernama assert. Tidak perlu instalasi, tidak ada dependensi, cukup require dan mulai periksa asumsi.

Modul assert layak diketahui. Modul ini mendukung pemeriksaan kewarasan cepat dalam skrip, mendasari banyak pelari pengujian, dan mengajarkan Anda apa sebenarnya sebuah *assertion* sebelum kerangka kerja apa pun mengemasnya. Panduan ini mencakup metode-metode penting, perbedaan *strict-versus-legacy* yang sering membingungkan, cara melakukan *assertion* pada galat dan kode asinkron, serta bagaimana modul yang sama membantu Anda memvalidasi respons API.

Apa yang dilakukan modul assert

Sebuah *assertion* adalah pernyataan yang harus benar agar program Anda dianggap benar. Ketika Anda menulis assert.strictEqual(total, 100), Anda menyatakan bahwa total harus sama dengan 100. Jika benar, tidak ada yang terjadi dan eksekusi berlanjut. Jika tidak, assert akan melemparkan AssertionError yang menghentikan eksekusi dan memberi tahu Anda apa yang salah.

Impor modul. Bentuk modern yang direkomendasikan adalah versi *strict*:

const assert = require('node:assert/strict');
// or with ES modules:
// import assert from 'node:assert/strict';

Assertion paling sederhana memeriksa bahwa suatu nilai adalah *truthy*:

const user = getUser(42);
assert(user, 'getUser should return a user object');

Argumen pertama adalah nilai yang sedang diuji. Argumen kedua, opsional, adalah pesan yang ditampilkan ketika *assertion* gagal. Selalu tulis pesan tersebut. Kegagalan yang menyatakan “getUser should return a user object” jauh lebih berguna daripada AssertionError kosong. Memahami *assertion* juga membantu ketika Anda beralih ke *API assertions* khusus dalam alat pengujian.

Mode *strict* versus mode *legacy*

Ini adalah hal terpenting yang harus dipahami dengan benar. Modul assert memiliki dua mode.

Mode *legacy*, yang Anda dapatkan dari require('node:assert'), menggunakan kesetaraan longgar (==) untuk assert.equal dan assert.deepEqual. Itu berarti assert.equal(1, '1') lulus, karena 1 == '1' adalah benar di JavaScript. Kesetaraan longgar adalah sumber bug yang terkenal.

Mode *strict*, yang Anda dapatkan dari require('node:assert/strict'), menggunakan kesetaraan *strict* (===) untuk semuanya. assert.equal(1, '1') gagal, sebagaimana mestinya, karena tipe datanya berbeda.

const looseAssert = require('node:assert');
looseAssert.equal(1, '1');        // passes, surprising and dangerous

const strict = require('node:assert/strict');
strict.equal(1, '1');             // throws AssertionError, correct

Gunakan mode *strict*. Tidak ada alasan bagus untuk menerima kesetaraan longgar dalam pengujian. Sisa panduan ini mengasumsikan node:assert/strict, di mana assert.equal berperilaku seperti assert.strictEqual.

Membandingkan nilai: equal dan strictEqual

assert.strictEqual(actual, expected) memeriksa bahwa dua nilai identik dengan ===. Ini adalah alat utama untuk tipe data primitif seperti angka, string, dan boolean.

const assert = require('node:assert/strict');

function priceWithTax(price, rate) {
  return price + price * rate;
}

assert.strictEqual(priceWithTax(100, 0.08), 108, 'tax calc should add 8 percent');
assert.strictEqual(typeof priceWithTax(100, 0.08), 'number', 'result should be a number');

Ada juga assert.notStrictEqual, yang lulus ketika kedua nilai tidak identik. Gunakan untuk mengkonfirmasi bahwa suatu nilai telah berubah:

const before = getCacheKey();
refreshCache();
const after = getCacheKey();
assert.notStrictEqual(before, after, 'cache key should change after refresh');

Untuk objek dan array, strictEqual tidak akan membantu. Dua literal objek dengan konten yang sama adalah referensi yang berbeda, jadi === mengembalikan *false*. Itulah gunanya kesetaraan mendalam (*deep equality*).

Membandingkan objek: deepStrictEqual

assert.deepStrictEqual(actual, expected) membandingkan struktur dan nilai secara rekursif. Dua objek lulus jika setiap kunci memiliki nilai yang sama persis (*strictly equal*), hingga ke tingkat terdalam.

const assert = require('node:assert/strict');

function buildOrder(id, items) {
  return { id, items, status: 'pending' };
}

assert.deepStrictEqual(
  buildOrder(7, ['keyboard', 'mouse']),
  { id: 7, items: ['keyboard', 'mouse'], status: 'pending' },
  'order object should match expected shape'
);

Ini adalah metode yang paling sering Anda gunakan saat menguji fungsi yang mengembalikan objek, dan terutama saat menguji respons API, karena *body* JSON adalah objek. Pasangannya assert.notDeepStrictEqual lulus ketika strukturnya berbeda.

Satu peringatan: deepStrictEqual juga memeriksa tipe data. Properti yang berisi angka 7 tidak akan cocok dengan properti yang berisi string '7'. Keketatan itu adalah sebuah fitur; ia menangkap penyimpangan tipe data dalam data Anda. Jika Anda menguji fungsi dengan banyak kombinasi input, panduan kami tentang *data-driven testing* dengan CSV dan JSON menunjukkan cara menskalakan *assertion* di seluruh kumpulan data.

Ketika deepStrictEqual gagal, Node mencetak *diff* yang menyoroti dengan tepat properti mana yang tidak sesuai. *Diff* tersebut adalah salah satu hal paling berguna tentang modul ini. Alih-alih menatap dua objek besar mencoba menemukan perbedaan, Anda membaca beberapa baris yang disorot. Untuk data bersarang, hal itu saja sudah membenarkan penggunaan deepStrictEqual daripada memeriksa setiap *field* secara manual dengan strictEqual.

Pencocokan parsial dengan assert.match dan assert.ok

Tidak setiap pemeriksaan memerlukan kesetaraan penuh. Terkadang Anda hanya peduli bahwa suatu nilai terlihat kira-kira benar. assert.ok(value) lulus kapan pun nilai tersebut adalah *truthy*, yang merupakan alat yang tepat untuk pemeriksaan “ini harus ada”: string yang tidak kosong, objek yang terdefinisi, hitungan bukan nol.

assert.match(string, regexp) memeriksa apakah sebuah string cocok dengan ekspresi reguler, dan assert.doesNotMatch memeriksa yang sebaliknya. Ini berguna untuk nilai-nilai yang konten pastinya bervariasi tetapi bentuknya tetap.

const assert = require('node:assert/strict');

function generateOrderId() {
  return 'ORD-' + Date.now();
}

const id = generateOrderId();

// the exact timestamp changes, so assert the format, not the value
assert.match(id, /^ORD-\d+$/, 'order id should be ORD- followed by digits');
assert.ok(id.length > 4, 'order id should not be empty');

Pola ini penting terutama untuk pengujian API, di mana respons mengandung *timestamp*, ID yang dihasilkan, dan *token* yang tidak dapat Anda prediksi. Anda menegaskan format dengan match dan keberadaan dengan ok, dan Anda menggunakan strictEqual untuk nilai-nilai yang benar-benar Anda kendalikan.

Menegaskan bahwa kode melempar galat

Terkadang perilaku yang benar berarti melemparkan galat. assert.throws(fn, expectedError) menjalankan fungsi dan hanya lulus jika fungsi tersebut melemparkan galat.

const assert = require('node:assert/strict');

function parsePort(value) {
  const port = Number(value);
  if (!Number.isInteger(port) || port < 1 || port > 65535) {
    throw new RangeError('port must be an integer between 1 and 65535');
  }
  return port;
}

// passes: invalid input should throw a RangeError
assert.throws(
  () => parsePort('70000'),
  RangeError,
  'out-of-range port should throw RangeError'
);

// you can also match the error message with a regex
assert.throws(
  () => parsePort('abc'),
  /must be an integer/,
  'non-numeric port should throw a descriptive error'
);

// passes: valid input should not throw
assert.doesNotThrow(
  () => parsePort('8080'),
  'a valid port should not throw'
);

Perhatikan bahwa Anda meneruskan sebuah fungsi, bukan sebuah panggilan. assert.throws(parsePort('70000')) akan mengeksekusi parsePort sebelum assert sempat melihatnya, dan galat akan keluar tanpa tertangkap. Selalu bungkus: () => parsePort('70000').

Melakukan *assertion* pada kode asinkron: rejects

Kode Node.js modern penuh dengan *promise*, dan *promise* yang ditolak adalah padanan asinkron dari galat yang dilemparkan. assert.rejects dan assert.doesNotReject menangani kasus tersebut. Keduanya mengembalikan *promise*, jadi Anda await mereka.

const assert = require('node:assert/strict');

async function fetchUser(id) {
  if (typeof id !== 'number') {
    throw new TypeError('id must be a number');
  }
  // ... real lookup would go here
  return { id, name: 'Dana Lee' };
}

async function runTests() {
  // passes: bad input rejects with a TypeError
  await assert.rejects(
    fetchUser('not-a-number'),
    TypeError,
    'string id should reject'
  );

  // passes: good input resolves without rejecting
  await assert.doesNotReject(
    fetchUser(101),
    'valid id should resolve cleanly'
  );
}

runTests();

Lupa untuk await panggilan assert.rejects adalah kesalahan umum. Tanpa await, fungsi pengujian selesai sebelum *assertion* terselesaikan, dan kegagalan menjadi penolakan yang tidak tertangani (*unhandled rejection*) alih-alih galat pengujian yang jelas.

Menggunakan assert untuk menguji respons API

Modul assert sangat berguna untuk memeriksa keluaran dari permintaan HTTP. Setelah Anda mengambil sebuah *endpoint*, Anda memiliki kode status dan *body* JSON, dan keduanya adalah hal yang dapat diasertifikasi.

const assert = require('node:assert/strict');

async function testGetUser() {
  const res = await fetch('https://api.example.com/users/101');

  // check the status code
  assert.strictEqual(res.status, 200, 'GET /users/101 should return 200');

  const body = await res.json();

  // check the shape and types of the response
  assert.strictEqual(typeof body.id, 'number', 'id should be a number');
  assert.strictEqual(body.id, 101, 'id should match the requested user');
  assert.ok(body.name, 'response should include a name');
  assert.ok(Array.isArray(body.roles), 'roles should be an array');
}

testGetUser().then(
  () => console.log('API test passed'),
  (err) => { console.error('API test failed:', err.message); process.exitCode = 1; }
);

Pola ini berhasil, dan mengajarkan dasar-dasarnya. Namun untuk *suite* pengujian API yang sebenarnya, Anda akan menginginkan eksekusi terstruktur, percobaan ulang (*retries*), penanganan lingkungan, dan pelaporan yang tidak disediakan oleh assert murni. Panduan kami tentang cara menulis skrip pengujian otomatis dan kerangka kerja otomatisasi API pytest mencakup langkah selanjutnya.

Jika Anda tidak ingin membangun *test harness* secara manual, Apidog memungkinkan Anda mendefinisikan permintaan API dan melampirkan *assertion* visual pada kode status, *header*, dan bidang JSON tanpa menulis kode *assertion* sama sekali. Anda dapat merangkai permintaan ke dalam skenario pengujian otomatis, menjalankannya di CI/CD, dan tetap beralih ke skrip khusus saat Anda membutuhkan kontrol yang diberikan oleh assert. Ini adalah jalur yang lebih cepat dari “Saya punya *endpoint*” menjadi “Saya punya *test suite*,” dan Anda dapat mengunduh Apidog serta menggunakannya secara gratis. Bersama dengan Apidog, modul assert Node.js mencakup pemeriksaan cepat dan *suite* lengkap.

Pertanyaan yang sering diajukan

Apakah saya perlu menginstal modul `assert`?

Tidak. assert sudah terpasang di Node.js. Impor dengan require('node:assert/strict') atau require('node:assert'). Tidak ada paket npm yang perlu diinstal dan tidak ada dependensi yang perlu dikelola. Awalan node: menjadikannya eksplisit bahwa Anda memuat modul inti.

Apa perbedaan antara `assert.equal` dan `assert.strictEqual`?

Dalam mode *legacy*, assert.equal menggunakan kesetaraan longgar (==) dan assert.strictEqual menggunakan kesetaraan *strict* (===). Dalam mode *strict*, yang dimuat melalui node:assert/strict, assert.equal berperilaku identik dengan assert.strictEqual. Selalu gunakan mode *strict* agar pemaksaan tipe tidak pernah secara diam-diam meloloskan pengujian.

Kapan saya harus menggunakan `deepStrictEqual` alih-alih `strictEqual`?

Gunakan strictEqual untuk tipe data primitif: angka, string, boolean. Gunakan deepStrictEqual untuk objek dan array, karena strictEqual membandingkan referensi dan dua objek terpisah tidak akan pernah setara referensi. Kapan pun Anda melakukan *assertion* pada *body* JSON atau objek yang dikembalikan, gunakan deepStrictEqual.

Haruskah saya menggunakan modul `assert` atau kerangka kerja pengujian seperti Jest?

Untuk skrip cepat dan pembelajaran, assert murni tidak masalah. Untuk *suite* pengujian yang sebenarnya, gunakan kerangka kerja. Node.js juga menyertakan *test runner* bawaan, node:test, yang berpasangan secara alami dengan assert dan memberi Anda organisasi pengujian, pelaporan, dan paralelisme tanpa dependensi eksternal.

Bagaimana cara menegaskan bahwa fungsi asinkron ditolak?

Gunakan assert.rejects, dan ingat untuk await itu. Teruskan *promise* atau panggilan fungsi asinkron, opsional dengan tipe galat yang diharapkan atau regex pesan. assert.rejects(somePromise, TypeError) hanya lulus jika *promise* ditolak dengan TypeError. Tanpa await, kegagalan menjadi penolakan yang tidak tertangani (*unhandled rejection*) alih-alih galat *assertion* yang jelas.

Mengembangkan API dengan Apidog

Apidog adalah alat pengembangan API yang membantu Anda mengembangkan API dengan lebih mudah dan efisien.