tutorial

41 Pengenalan Unit Test untuk Resolver

41 Pengenalan Unit Test untuk Resolver

Unit testing telah menjadi bagian fundamental dalam siklus hidup pengembangan perangkat lunak modern. Tidak hanya memastikan bahwa kode berjalan sebagaimana mestinya, tetapi juga membantu menjaga kualitas kode seiring pertumbuhan dan perubahan kebutuhan sistem. Dalam artikel ke-41 dari serial pengenalan testing ini, saya akan membahas secara spesifik mengenai unit test untuk resolver—sebuah komponen yang sering diabaikan dalam pengujian, khususnya pada aplikasi yang menggunakan GraphQL ataupun pola desain resolver pada backend tradisional.

Artikel ini akan mengupas tuntas mulai dari pengertian resolver, pentingnya suatu unit test, sampai contoh implementasi lengkap dengan simulasi, tabel, dan diagram alur menggunakan mermaid.


Apa Itu Resolver?

Sebelum kita terjun ke unit testing, penting untuk memahami apa itu resolver.

Resolver adalah fungsi yang bertanggung jawab untuk mengembalikan data pada permintaan tertentu, biasanya pada pola arsitektur GraphQL. Namun, istilah resolver juga bisa digunakan pada sistem yang memetakan permintaan ke handler dinamis, seperti pada service locator pattern dan API gateway.

Sebagai ilustrasi, dalam GraphQL, resolver biasanya terlihat seperti ini:

const resolvers = {
  Query: {
    user: (parent, args, context) => {
      // Logic untuk mendapatkan user berdasarkan args.id
      return getUserById(args.id);
    },
  },
};

Kenapa Unit Test untuk Resolver Penting?

Tabel berikut merangkum alasan pentingnya melakukan unit test pada resolver:

AlasanPenjelasan
Isolasi logika bisnisMemastikan setiap fungsi dapat berjalan mandiri.
Deteksi error lebih diniMengidentifikasi bug sebelum ke tahap integrasi/deploy.
Mencegah regresiMengurangi resiko error saat kode diperbarui.
Dokumentasi kasus pinggiranKasus tepi terdokumentasi dengan ujiannya.
Kepercayaan tim/developerUnit test menjadi kontrak yang bisa diandalkan.

Struktur Standar Resolver

Mari kita lihat template resolver berikut, umumnya pada proyek Node.js + GraphQL:

// resolvers/user.js

const getUserById = require('../services/userService').getUserById;

const userResolver = async (_, { id }, context) => {
  // Validasi input
  if (!id) throw new Error('User ID is required');
  // Mendapatkan data user
  const user = await getUserById(id);
  if (!user) throw new Error('User not found');
  return user;
};

module.exports = userResolver;

Pada resolver di atas, kita butuh memastikan tiga hal:

  1. Input ID harus ada.
  2. Fungsi getUserById dipanggil dan hasilnya benar.
  3. Error dilempar jika user tidak ditemukan.

Unit Test Resolver: Simulasi Skenario

Untuk melakukan unit test, kita wajib mengisolasi depedensi eksternal seperti database/service eksternal menggunakan mocking.

Tools yang Digunakan

  • Jest untuk test runner dan mocking.
  • Sinon (opsional), jika butuh spy/stub lebih lanjut.

Penataan Berkas

/services
  userService.js
/resolvers
  user.js
/tests
  userResolver.test.js

Contoh Unit Test

// tests/userResolver.test.js

const userResolver = require('../resolvers/user');
const userService = require('../services/userService');

jest.mock('../services/userService');

describe('User Resolver Unit Test', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });

  it('should throw error if id is missing', async () => {
    await expect(userResolver(null, {}, {})).rejects.toThrow('User ID is required');
  });

  it('should call getUserById with correct id', async () => {
    userService.getUserById.mockResolvedValue({ id: '123', name: 'Andy' });
    const result = await userResolver(null, { id: '123' }, {});
    expect(userService.getUserById).toBeCalledWith('123');
    expect(result).toEqual({ id: '123', name: 'Andy' });
  });

  it('should throw error if user not found', async () => {
    userService.getUserById.mockResolvedValue(null);
    await expect(userResolver(null, { id: '321' }, {})).rejects.toThrow('User not found');
  });
});

Diagram Alur Resolver dan Testing

Untuk memperjelas, berikut adalah flow sederhana resolver dan pengujiannya dalam diagram mermaid:

flowchart TD
    A[Mulai Unit Test] --> B{ID Diberikan?}
    B -- Tidak --> C[Tolak dengan Error: ID is required]
    B -- Ya --> D[Panggil getUserById(id)]
    D --> E{User ditemukan?}
    E -- Tidak --> F[Tolak dengan Error: User not found]
    E -- Ya --> G[Kembalikan User]

Simulasi Jalannya Unit Test

Mari simulasi proses pengujian dengan urutan berikut:

  1. Test 1: Tanpa argumen ID.
    • Resolver langsung validasi dan melempar error.
  2. Test 2: Argument ID diberikan dan user ditemukan.
    • Mock service mengembalikan data dummy, resolver mengembalikan hasil.
  3. Test 3: Argument ID diberikan tapi user null.
    • Mock mengembalikan null, sehingga resolver melempar error.
No.SkenarioInputMock OutputExpected Hasil
1ID tidak diberikan{}-Error: ID is required
2User ditemukan{id: '123'}{id:'123', name}User Object
3User tidak ditemukan{id: '321'}nullError: User not found

Best Practice dalam Unit Test Resolver

  1. Test semua path: Happy path dan error path.
  2. Mock depedensi external: Jangan membiarkan test memanggil service/database asli.
  3. Kombinasikan dengan coverage: Pastikan path critical sudah teruji.
  4. Buat test readable: Deskripsi test harus jelas seperti specification.
  5. Jangan test integrasi disini: Unit test hanya menguji 1 unit/kontainer.

Kesimpulan

Unit testing pada resolver memang sering diremehkan, apalagi karena resolver terasa seperti fungsi sederhana yang “cuma jadi perantara”. Namun, sebagaimana kita lihat, unit test pada resolver itu krusial. Ia mengawasi integrasi antar domain logic, validasi input, error handling, hingga keandalan response kepada frontend/API client.

Dengan mengikuti praktik terbaik dan memanfaatkan tools seperti Jest, kita dapat menjaga kualitas kode sekaligus membuat perubahan lebih nyaman di masa depan. Semoga penjelasan, contoh, simulasi dan tabel pada artikel ke-41 ini memberikan wawasan yang cukup untuk mulai menguji resolver pada proyek Anda!


Tulisan dan diagram di atas adalah bagian dari Seri Testing Modern di Medium. Jangan lewatkan artikel selanjutnya seputar teknik testing yang lebih advance!

comments powered by Disqus