Belajar ElysiaJS - Testing dengan Bun Test & Supertest
Episode 17 of 21

Belajar ElysiaJS - Testing dengan Bun Test & Supertest

Mengimplementasikan testing di ElysiaJS: unit testing routes dengan Bun.test(), integration testing dengan supertest, E2E testing dengan running server, dan code coverage untuk memastikan kualitas kode.

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

Setelah di episode 16 kita memahami performance optimization, pada episode ini kita akan memahami testing — lapisan jaminan kualitas yang memastikan kode berfungsi sebagaimana mestinya dan tidak rusak saat ada perubahan.

Unit Testing Routes

Bun.test() — Built-in Test Runner

Bun memiliki test runner bawaan yang sangat cepat:

test/routes.test.ts: unit test pertama
import { describe, it, expect } from 'bun:test'
import { Elysia } from 'elysia'
 
const app = new Elysia()
  .get('/', () => 'Hello Elysia!')
  .get('/user/:id', ({ params }) => ({ id: params.id }))
 
describe('Routes', () => {
  it('should return hello message', async () => {
    const res = await app.handle(new Request('http://localhost/'))
    expect(res.status).toBe(200)
    expect(await res.text()).toBe('Hello Elysia!')
  })
 
  it('should return user by id', async () => {
    const res = await app.handle(new Request('http://localhost/user/123'))
    expect(res.status).toBe(200)
    const data = await res.json()
    expect(data.id).toBe('123')
  })
})

app.handle() memungkinkan kalian menguji route tanpa menjalankan server — test menjadi sangat cepat.

Test dengan Validasi

Test validasi otomatis
it('should return 422 for invalid body', async () => {
  const res = await app.handle(
    new Request('http://localhost/users', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name: '' }),
    })
  )
  expect(res.status).toBe(422)
})

Integration Testing

Supertest untuk HTTP Testing

Install supertest
bun add -D supertest @types/supertest
Integration test dengan supertest
import request from 'supertest'
 
describe('API Integration', () => {
  it('should create and retrieve user', async () => {
    const createRes = await request('http://localhost:3000')
      .post('/users')
      .send({ name: 'John', email: 'john@example.com' })
      .expect(201)
 
    const userId = createRes.body.id
 
    const getRes = await request('http://localhost:3000')
      .get(`/users/${userId}`)
      .expect(200)
 
    expect(getRes.body.name).toBe('John')
  })
})

Test Database

Gunakan in-memory SQLite untuk testing:

In-memory database untuk test
import { Database } from 'bun:sqlite'
import { drizzle } from 'drizzle-orm/bun-sqlite'
 
function createTestDb() {
  const sqlite = new Database(':memory:')
  return drizzle(sqlite)
}

E2E Testing

Full Server Test

E2E test dengan running server
describe('E2E Auth Flow', () => {
  let server: subprocess
 
  beforeAll(async () => {
    server = Bun.spawn(['bun', 'run', 'src/index.ts'])
    await Bun.sleep(1000) // wait for server
  })
 
  afterAll(() => server.kill())
 
  it('should login and access protected route', async () => {
    const loginRes = await fetch('http://localhost:3000/auth/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ email: 'test@example.com', password: 'pass' }),
    })
    const { token } = await loginRes.json()
 
    const profileRes = await fetch('http://localhost:3000/profile', {
      headers: { Authorization: `Bearer ${token}` },
    })
    expect(profileRes.status).toBe(200)
  })
})

Coverage

Jalankan test dengan coverage
bun test --coverage

Coverage report menunjukkan persentase kode yang teruji. Target: minimal 80% line coverage untuk kode produksi.

Tip

Mulai dengan unit testing untuk route handler, lalu tambahkan integration testing untuk alur yang melibatkan database, dan E2E testing untuk flow kritis seperti autentikasi.

Penutup

Pada episode 17 ini, kalian telah memahami testing di ElysiaJS — dari unit test hingga E2E dan coverage.

Inti yang harus dibawa pulang:

  • app.handle() memungkinkan unit test tanpa running server.
  • Supertest untuk integration testing HTTP.
  • In-memory SQLite untuk test database yang cepat.
  • bun test --coverage untuk code coverage report.

Di episode 18 selanjutnya kita akan memahami project structure dan scalability — struktur folder, modularisasi dengan plugin, scaling ke microservices, dan graceful shutdown. Sampai jumpa di episode 18!

Belajar ElysiaJS - Testing dengan Bun Test & Supertest | Belajar ElysiaJS