Episode ini membahas pengujian lapisan API dan HTTP: mocking request dengan fetch, axios, dan nock, menguji API client modules, menjalankan integration tests dengan test servers, serta strategi isolasi untuk menghindari test yang flaky.

Kode yang berbicara ke server eksternal adalah sumber utama test flaky: jaringan lambat, server down, atau data yang berubah bisa membuat test gagal tanpa sebab. Episode 12 membahas strategi menguji API & HTTP layers dengan benar — mocking request memakai fetch, axios, dan nock, menguji API client modules secara terisolasi, menjalankan integration tests dengan test servers, dan menjaga isolasi agar suite tetap deterministik.
Tujuan akhirnya jelas: test yang cepat, deterministik, dan tidak bergantung pada kondisi jaringan. Mari bedah tekniknya satu per satu.
Untuk kode yang memakai fetch, mock global fetch dengan jest.fn:
global.fetch = jest.fn();
async function ambilPengguna(id) {
const res = await fetch(`/api/pengguna/${id}`);
return res.json();
}
test("mengambil data pengguna", async () => {
fetch.mockResolvedValue({
ok: true,
json: async () => ({ id: 1, nama: "arif" }),
});
const hasil = await ambilPengguna(1);
expect(hasil.nama).toBe("arif");
expect(fetch).toHaveBeenCalledWith("/api/pengguna/1");
});fetch.mockResolvedValue({...}) membuat fetch mengembalikan respons yang sudah ditentukan, sehingga test tidak pernah menyentuh jaringan. Assertion toHaveBeenCalledWith memverifikasi URL dan parameter yang dipakai.
Untuk axios, mocking lebih mudah lewat module mock:
jest.mock("axios");
import axios from "axios";
axios.get.mockResolvedValue({ data: { pesan: "ok" } });
test("axios.get mengembalikan data", async () => {
const { data } = await axios.get("/api/cek");
expect(data.pesan).toBe("ok");
});jest.mock("axios") membuat automatic mock untuk seluruh modul. Karena axios adalah modul eksternal, cara ini mengganti semua fungsinya dengan jest.fn yang bisa diatur perilakunya.
nock mengambil pendekatan berbeda: mencegat request HTTP nyata di level transport, bukan mengganti fungsi:
npm install --save-dev nockimport nock from "nock";
test("request dicegat nock", async () => {
nock("https://api.example.com")
.get("/status")
.reply(200, { status: "ok" });
const res = await fetch("https://api.example.com/status");
expect(await res.json()).toEqual({ status: "ok" });
nock.cleanAll();
});nock("https://api.example.com") membuat interceptor untuk host tersebut. Kelebihannya: tidak perlu mengubah kode yang diuji — request tetap berjalan normal, hanya saja dicegat sebelum meninggalkan proses.
API client modules paling mudah diuji ketika tanggung jawabnya tunggal: membangun URL, mengatur header, mengirim request, dan mengurai respons. Mock transport (fetch atau axios), lalu fokus menguji logika client itu sendiri:
function apiClient(baseUrl) {
return {
getStatus: async () => {
const res = await fetch(`${baseUrl}/status`);
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
return res.json();
},
};
}Dengan transport yang di-mock, kalian bisa menguji perilaku client terhadap berbagai skenario: respons ok, status error, waktu timeout, dan JSON yang tidak valid — tanpa server nyata.
Kadang integration test perlu server sungguhan. Solusi paling umum: server HTTP ringan yang dijalankan di dalam test:
import { createServer } from "node:http";
test("end-to-end dengan server lokal", async () => {
const server = createServer((req, res) => {
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ pesan: "dari server" }));
});
await new Promise((resolve) => server.listen(0, resolve));
const port = server.address().port;
const res = await fetch(`http://localhost:${port}/`);
expect(await res.json()).toEqual({ pesan: "dari server" });
await new Promise((resolve) => server.close(resolve));
});server.listen(0, resolve) meminta port acak agar tidak bentrok antar test. Integration test ini melatih seluruh stack request — termasuk parsing body dan status code — tanpa jaringan eksternal.
Beberapa aturan untuk menjaga isolasi network test:
afterEach dengan jest.clearAllMocks() atau nock.cleanAll().Ketika sebuah test tiba-tiba gagal karena "jaringan", itu tanda desain yang salah. Test yang baik tidak peduli jaringan sedang hidup atau mati.
Episode 12 membekali kalian pengujian lapisan API dan HTTP: mocking fetch dan axios, mencegat request dengan nock, menguji API client modules secara terisolasi, dan menjalankan integration tests dengan test servers lokal.
Inti yang harus dibawa pulang:
jest.fn agar test tidak menyentuh jaringan.jest.mock("axios") membuat automatic mock untuk modul eksternal.afterEach agar isolasi antar test terjaga.Di episode 13 selanjutnya kita akan membahas security & test reliability — mencegah test membocorkan data sensitif, mengisolasi logika spesifik environment, membuat test yang deterministik dan repeatable, serta menghindari flaky tests dengan setup dan teardown yang benar.