Belajar Node.js - Testing API dan Integrasi dengan Tools Modern
Episode 18 of 23

Belajar Node.js - Testing API dan Integrasi dengan Tools Modern

Episode ini menguji API dengan tools modern: test runner bawaan node:test, pengujian endpoint HTTP dengan supertest, mocking untuk isolasi, serta pengukuran coverage. Kalian mengunci perilaku API agar perubahan tidak merusak fitur.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Kode yang tidak diuji adalah bom waktu: satu perubahan kecil bisa merusak fitur yang tidak terduga. Testing mengubah itu — kalian menulis ekspektasi sebagai kode, lalu menjalankannya setiap kali aplikasi berubah. Di dunia Node.js, tools testing kini semakin sederhana.

Episode 18 mempraktikkan pengujian API modern: test runner bawaan node:test, pengujian endpoint HTTP dengan supertest, mocking untuk mengisolasi database, dan pengukuran coverage. Di akhir episode, kalian punya suite test yang berjalan di terminal dan siap dipakai di CI.

Test Runner Bawaan node:test

Mulai dari Node.js versi 18, test runner tersedia tanpa install apa pun. Modul node:test menyediakan test dan assert:

JSTest pertama dengan node:test
import { test } from "node:test";
import assert from "node:assert/strict";
 
function tambah(a, b) {
  return a + b;
}
 
test("tambah menjumlahkan dua angka", () => {
  assert.equal(tambah(2, 3), 5);
});

test("nama", () => ...) mendefinisikan kasus uji, dan assert.equal(tambah(2, 3), 5) memeriksa hasil. Jalankan dengan node --test: runner menemukan file test, menjalankannya, dan melaporkan hasilnya.

Menjalankan Suite

Menjalankan test
node --test

node --test mencari file yang cocok dengan pola seperti *.test.js dan menjalankannya. Tambahkan "test": "node --test" ke scripts di package.json agar seluruh tim memakai perintah yang sama — kelak di episode 22, perintah ini dipakai oleh pipeline CI.

Menguji HTTP API dengan Supertest

Mengetes Tanpa Menyalakan Server

supertest memungkinkan menguji server HTTP tanpa membukanya ke port — request dikirim ke fungsi server secara langsung:

Install supertest
npm install --save-dev supertest

npm install --save-dev supertest menambahkan supertest ke devDependencies karena hanya dipakai saat development dan testing.

Menguji Endpoint Express

JSTest endpoint dengan supertest
import { test } from "node:test";
import assert from "node:assert/strict";
import request from "supertest";
import { app } from "./app.js";
 
test("GET /api/pengguna mengembalikan daftar", async () => {
  const respons = await request(app).get("/api/pengguna");
 
  assert.equal(respons.status, 200);
  assert.equal(respons.body.status, "success");
  assert.ok(Array.isArray(respons.body.data));
});

request(app).get("/api/pengguna") mengirim request ke aplikasi Express tanpa menyalakan server. Perhatikan bahwa app harus diekspor dari modul terpisah, dan app.listen dipindah ke file lain — pola ini membuat aplikasi mudah diuji. Assertion memeriksa status code dan bentuk body.

Mocking dan Isolasi

Menyuntikkan Pengganti Database

Test yang bergantung pada database sungguhan lambat dan rapuh. Gunakan mocking untuk mengganti bagian eksternal dengan perilaku yang kita kendalikan. Cara paling sederhana: terima dependensi sebagai parameter:

JSFungsi dengan dependensi disuntikkan
export function buatHandler(database) {
  return async (req, res) => {
    const data = await database.ambilSemua();
    res.json(data);
  };
}

Dengan pola dependency injection di atas, test bisa memasukkan database tiruan. database.ambilSemua() diimplementasikan sebagai fungsi yang mengembalikan data palsu — tanpa koneksi nyata. node:test juga menyediakan mock.fn dan mock.method untuk membuat pengganti fungsi ini.

Menguji Kasus Error

Jangan hanya menguji jalan sukses. Uji juga respons error agar aplikasi berperilaku benar saat sesuatu gagal:

JSTest kasus error
test("404 ketika pengguna tidak ada", async () => {
  const respons = await request(app).get("/api/pengguna/999");
 
  assert.equal(respons.status, 404);
  assert.equal(respons.body.status, "error");
});

Test di atas memastikan pengguna dengan id yang tidak ada mendapat 404. Kasus error yang diuji dengan baik mencegah bug yang hanya muncul di kondisi tertentu — dan memberi keyakinan saat melakukan refactor.

Coverage dan CI

Mengukur Seberapa Banyak Kode Teruji

Coverage menunjukkan persentase kode yang dieksekusi oleh test. Node.js punya coverage bawaan via V8:

Jalankan test dengan coverage
node --test --experimental-test-coverage

node --test --experimental-test-coverage melaporkan baris, fungsi, dan branch yang tercakup test. Target yang wajar bukan 100 persen, tapi coverage yang stabil dan terarah pada kode penting — coverage tinggi tidak menjamin kode benar, hanya memberi sinyal mana yang belum diuji.

Menghubungkan ke CI

Test yang tidak berjalan otomatis hanya sekedar naskah. Di episode 22, kita akan menyambungkan npm test ke pipeline CI sehingga setiap push menjalankan seluruh suite — perubahan yang merusak test langsung menggagalkan build.

Penutup

Inti yang harus dibawa pulang:

  • node:test menyediakan runner dan assertion bawaan tanpa install.
  • Supertest menguji endpoint HTTP tanpa menyalakan server.
  • Pisahkan app dari listen agar mudah diuji.
  • Mock dependensi eksternal untuk test yang cepat dan stabil.
  • Uji kasus sukses dan error secara seimbang.
  • Coverage diukur dan dihubungkan ke CI.

Di episode 19 selanjutnya kita akan membahas performance tuning, event loop, dan profiling — fase-fase event loop, penyebab blocking, profiling CPU dengan Node Inspector, load testing dengan autocannon, dan deteksi kebocoran memori. Kalian akan membuat API yang cepat dan stabil di bawah beban.

Belajar Node.js - Testing API dan Integrasi dengan Tools Modern | Belajar Node.js