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