Episode ini membahas testing di NestJS: unit testing dengan Jest, integration testing memakai @nestjs/testing, E2E testing dan setup test database, serta code coverage, linting, dan static analysis untuk menjaga kualitas kode.

Aplikasi tanpa test adalah bom waktu. NestJS dirancang dengan testing sebagai prioritas — dependency injection membuat penggantian dependensi dengan mock menjadi sangat mudah. Episode 17 membahas unit test, integration test, dan E2E test untuk membangun kebiasaan menulis test yang menjaga kualitas kode.
Nest CLI sudah mengonfigurasi Jest saat membuat project. Untuk menjalankan test:
npm run testJest menemukan file dengan akhiran .spec.ts dan menjalankannya — panggil lewat npm run test.
Unit test fokus pada satu unit — misalnya sebuah service, dengan dependensi di-mock:
import { Test } from "@nestjs/testing";
import { UsersService } from "./users.service";
describe("UsersService", () => {
let service: UsersService;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
providers: [UsersService],
}).compile();
service = moduleRef.get(UsersService);
});
it("harus mengembalikan daftar user", () => {
const result = service.findAll();
expect(result).toContain("Arman");
});
});Test.createTestingModule membuat module testing yang mirip dengan runtime. it dan expect adalah API bawaan Jest.
Saat service bergantung pada repository, ganti dependensi asli dengan useValue:
const mockRepo = {
find: jest.fn().mockResolvedValue([{ id: 1, name: "Arman" }]),
};
const moduleRef = await Test.createTestingModule({
providers: [UsersService, { provide: "UserRepository", useValue: mockRepo }],
}).compile();Dengan useValue, dependensi asli diganti mock — test menjadi cepat dan terisolasi dari database.
Integration test menggabungkan beberapa komponen nyata — controller, service, dan module — sambil tetap meng-mock dependensi eksternal seperti database.
describe("UsersController", () => {
let controller: UsersController;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
controllers: [UsersController],
providers: [
UsersService,
{ provide: "UserRepository", useValue: mockRepo },
],
}).compile();
controller = moduleRef.get(UsersController);
});
it("harus mengembalikan user", async () => {
const result = await controller.findAll();
expect(result).toHaveLength(1);
});
});NestJS menyediakan .overrideProvider().useValue() untuk mengganti provider saat test — berguna saat menguji module penuh tanpa menjalankan dependensi yang berat.
E2E test mem-bootstrap seluruh aplikasi dan mengirim request HTTP nyata memakai supertest:
import * as request from "supertest";
import { Test } from "@nestjs/testing";
import { INestApplication } from "@nestjs/common";
import { AppModule } from "../src/app.module";
describe("App (e2e)", () => {
let app: INestApplication;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleRef.createNestApplication();
await app.init();
});
it("GET / mengembalikan Hello World", () => {
return request(app.getHttpServer())
.get("/")
.expect(200)
.expect("Hello World!");
});
});Jalankan dengan npm run test:e2e. File E2E berada di folder test/ dengan akhiran .e2e-spec.ts.
Untuk E2E yang menyentuh database, gunakan database test terpisah atau in-memory:
TypeOrmModule.forRoot({
type: "sqlite",
database: ":memory:",
autoLoadEntities: true,
synchronize: true,
})Setiap test dimulai dengan database bersih, hasil test jadi deterministik dan cepat.
Jest menghitung seberapa banyak kode yang diuji:
npm run test -- --coverageLaporan coverage menunjukkan baris yang belum diuji. Target sehat biasanya 80 persen ke atas untuk kode penting.
NestJS menggunakan ESLint dan TypeScript compiler untuk menangkap masalah sejak awal:
npm run lintLint menangkap kesalahan gaya dan bug umum. Tambahan seperti TypeScript strict mode dan tipe yang tepat memberi lapisan static analysis tambahan sebelum kode berjalan.
Episode 17 membangun budaya testing. Inti yang harus dibawa pulang:
Test.createTestingModule membuat module testing seperti runtime.