Belajar Jest - Asynchronous Testing
Episode 6 of 23

Belajar Jest - Asynchronous Testing

Episode ini membekali kalian teknik menguji kode async: menangani promise dengan matchers resolves dan rejects, pola async/await, callback berbasis done, serta pengendalian waktu dengan fake timers agar test cepat dan deterministik.

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

Pendahuluan

Hampir semua aplikasi modern penuh dengan operasi asynchronous: mengambil data dari API, membaca file, menunggu timeout, atau menjalankan job di background. Jika kalian tidak tahu cara menguji kode async dengan benar, test akan sering gagal secara acak — atau lebih buruk, lulus tanpa benar-benar menguji apa-apa.

Episode 6 mengajarkan empat teknik inti: menguji promise dengan resolves dan rejects, menulis test memakai async/await, menguji callback berbasis done, dan mengendalikan timer dengan fake timers. Setelah episode ini, kalian akan bisa menulis test async yang cepat, deterministik, dan bebas dari flakiness.

Testing Promises dengan resolves dan rejects

Matcher resolves dan rejects

Jest menyediakan dua matcher khusus untuk promise: resolves dan rejects. Keduanya membuat assertion terhadap promise tanpa perlu menangani then dan catch secara manual:

JSMenguji promise yang resolve dan reject
function ambilData(id) {
  return new Promise((resolve, reject) => {
    if (id > 0) {
      resolve({ id, nama: "arif" });
    } else {
      reject(new Error("id tidak valid"));
    }
  });
}
 
test("resolve dengan data", () => {
  return expect(ambilData(1)).resolves.toEqual({ id: 1, nama: "arif" });
});
 
test("reject dengan error", () => {
  return expect(ambilData(0)).rejects.toThrow("id tidak valid");
});

expect(ambilData(1)).resolves.toEqual(...) membaca bahwa promise akan resolve menjadi objek yang setara. Penting untuk mengembalikan assertion dengan return — tanpa itu Jest menganggap test selesai sebelum promise selesai, dan test selalu lulus.

Async/await Tests

Cara yang paling mudah dibaca adalah menulis fungsi test sebagai fungsi async dan memakai await untuk menunggu promise:

JSTest async dengan await
test("await langsung di test", async () => {
  const data = await ambilData(2);
  expect(data.nama).toBe("arif");
});
 
test("menunggu beberapa promise sekaligus", async () => {
  const hasil = await Promise.all([ambilData(1), ambilData(2)]);
  expect(hasil).toHaveLength(2);
});

Dengan pola async () => {} di dalam test, Jest menunggu fungsi tersebut selesai sebelum menilai hasilnya. Kombinasi Promise.all sangat berguna untuk menguji beberapa operasi async yang saling independen sekaligus.

Menguji Error pada Async

Untuk memeriksa bahwa sebuah operasi async melempar error, kalian menunggu reject dan menyatakannya:

JSMenguji error async
test("async mengembalikan error", async () => {
  await expect(ambilData(-1)).rejects.toThrow("id tidak valid");
});
 
test("try catch untuk menangkap error", async () => {
  await expect(ambilData(-1)).rejects.toBeInstanceOf(Error);
});

Pola await expect(...).rejects... menunggu reject yang diperkirakan terjadi. Tanpa await, assertion rejects tidak akan dievaluasi dan test akan lulus secara keliru.

Callbacks dan done

Memakai done untuk Callback-style Code

Tidak semua kode menggunakan promise. Untuk fungsi berbasis callback, Jest menyediakan parameter done:

JSCallback dengan done
function prosesLambat(input, cb) {
  setTimeout(() => {
    if (input) {
      cb(null, `hasil ${input}`);
    } else {
      cb(new Error("input kosong"));
    }
  }, 50);
}
 
test("callback sukses", (done) => {
  prosesLambat("data", (err, hasil) => {
    expect(err).toBeNull();
    expect(hasil).toBe("hasil data");
    done();
  });
});
 
test("callback error", (done) => {
  prosesLambat("", (err) => {
    expect(err.message).toBe("input kosong");
    done();
  });
});

Parameter done adalah fungsi yang harus dipanggil setelah assertion selesai. Jika done tidak pernah dipanggil, Jest akan gagalkan test karena timeout — ini melindungi kalian dari callback yang tidak pernah terpanggil.

Handling Timers dan Fake Timers

Mengapa Fake Timers Dibutuhkan

Test yang menunggu setTimeout selama beberapa detik akan membuat suite lambat. Jest menyediakan fake timers: timer palsu yang bisa dimajukan secara instan. Dengan jest.useFakeTimers(), Jest mengganti setTimeout, setInterval, dan Date dengan versi yang bisa dikendalikan.

JSFake timers dengan advanceTimersByTime
jest.useFakeTimers();
 
function penjadwal(ms, cb) {
  setTimeout(cb, ms);
}
 
test("penjadwal berjalan lebih cepat", () => {
  const cb = jest.fn();
  penjadwal(10000, cb);
 
  expect(cb).not.toHaveBeenCalled();
 
  jest.advanceTimersByTime(10000);
  expect(cb).toHaveBeenCalledTimes(1);
});

jest.advanceTimersByTime(10000) memajukan waktu palsu sebanyak 10 detik dalam satu langkah, tanpa benar-benar menunggu. Inilah cara menguji logika timeout dan retry dengan kecepatan penuh. Selalu panggil jest.useRealTimers() setelah selesai, misalnya di dalam afterEach, agar timer nyata kembali normal.

Kombinasi Fake Timers dan Promise

Kadang kode async menggunakan timer sekaligus promise. Pastikan urutan eksekusi dipertimbangkan — jalankan jest.advanceTimersByTime lalu tunggu microtask dengan await Promise.resolve(). Pola ini membuat test tetap deterministik meskipun memakai kombinasi timer dan promise.

Penutup

Episode 6 mengubah test async dari sumber flakiness menjadi alat yang andal: matcher resolves dan rejects untuk promise, pola async/await yang mudah dibaca, done untuk callback, dan fake timers untuk mengendalikan waktu.

Inti yang harus dibawa pulang:

  • Selalu return atau await assertion yang melibatkan promise.
  • resolves dan rejects membuat assertion promise tanpa then dan catch.
  • Fungsi test async menunggu selesai sebelum dinilai.
  • Callback memakai parameter done; tanpa dipanggil, test gagal karena timeout.
  • Fake timers memajukan waktu secara instan dengan advanceTimersByTime.
  • Kembalikan timer nyata dengan jest.useRealTimers() setelah test selesai.

Di episode 7 selanjutnya kita akan membahas snapshot testing — konsep membandingkan output serialized, penggunaan toMatchSnapshot(), cara memperbarui snapshot dengan aman lewat version control, hingga penerapannya untuk React components. Ini salah satu fitur khas yang membedakan Jest dari framework lain.

Belajar Jest - Asynchronous Testing | Belajar Jest