Recraftory

Mocking

Mengisolasi unit test dengan memalsukan dependensi

Apa itu Mocking

  • Teknik membuat objek palsu untuk menggantikan dependensi nyata
  • Memungkinkan unit test berjalan tanpa database, API, atau file system
  • Mengontrol perilaku dependensi agar test tetap deterministik

Mengapa Mocking Penting

  • Unit test harus terisolasi dari dependensi eksternal
  • Dependensi nyata bisa lambat atau tidak tersedia saat test
  • Memudahkan mensimulasikan edge case seperti error atau timeout

Jenis-Jenis Test Double

Dummy

  • Objek yang diberikan sebagai parameter tapi tidak digunakan
  • Hanya untuk memenuhi signature fungsi

Fake

  • Implementasi sederhana yang bekerja tapi tidak untuk production
  • Contoh: in-memory database sebagai pengganti database nyata

Stub

  • Memberikan response tetap untuk panggilan tertentu
  • Tidak memeriksa bagaimana dipanggil, hanya memberikan hasil

Spy

  • Merekam informasi tentang bagaimana dipanggil
  • Bisa memverifikasi fungsi dipanggil berapa kali dan dengan argumen apa

Mock

  • Objek dengan ekspektasi tentang bagaimana seharusnya dipanggil
  • Test akan gagal jika ekspektasi tidak terpenuhi

Contoh Mocking dengan Jest

// Module yang di-mock
import { kirimEmail } from './emailService';
jest.mock('./emailService');

// Fungsi yang diuji
async function daftarUser(user) {
  await simpanKeDatabase(user);
  await kirimEmail(user.email, 'Selamat datang!');
  return user;
}

// Test
it('harus mengirim email selamat datang', async () => {
  const user = { email: 'andi@email.com', nama: 'Andi' };

  await daftarUser(user);

  expect(kirimEmail).toHaveBeenCalledWith('andi@email.com', 'Selamat datang!');
});

Contoh Stub

const stubRepository = {
  cariUser: jest.fn().mockResolvedValue({ id: 1, nama: 'Andi' })
};

Contoh Spy

it('harus memanggil logger saat error', () => {
  const spy = jest.spyOn(console, 'error').mockImplementation(() => {});

  fungsiYangMelemparError();

  expect(spy).toHaveBeenCalledTimes(1);
  spy.mockRestore();
});

Kapan Menggunakan Mocking

Gunakan Mocking

  • Saat dependensi lambat seperti database atau API
  • Saat dependensi tidak deterministik seperti waktu atau random
  • Saat membutuhkan simulasi error atau edge case

Hindari Mocking Berlebihan

  • Jangan mock library internal yang sedang diuji
  • Jangan mock terlalu banyak sehingga test tidak merepresentasikan realitas
  • Integration test seharusnya menggunakan dependensi nyata

Praktik Terbaik

  • Mock di level boundary, jangan mock internal logic
  • Gunakan manual mock untuk modul yang sering di-mock
  • Pastikan mock di-reset sebelum setiap test
  • Verifikasi mock dipanggil dengan argumen yang benar