So Sánh Chi Tiết Giữa 3 Cơ Chế Kiểm Tra Trong Ứng Dụng NestJS
Giới Thiệu
Trong quá trình phát triển phần mềm, việc kiểm tra ứng dụng là điều cực kỳ quan trọng để đảm bảo chất lượng và tính ổn định. Bài viết này sẽ so sánh ba cơ chế kiểm tra chính trong ứng dụng NestJS: Unit Test, Integration Test và End-to-End (e2e) Test, cung cấp cái nhìn rõ ràng về đặc điểm, mục tiêu và cách sử dụng mỗi loại kiểm tra.
1. Kiểm Tra Đơn Vị (Unit Test)
- Mục tiêu: Kiểm tra logic của các thành phần riêng lẻ như class, function, hoặc module.
- Phạm vi: Tập trung vào việc kiểm tra một đơn vị code cụ thể và sử dụng mock cho tất cả các dependencies.
- Đặc điểm:
- Tập trung vào logic nội bộ của thành phần.
- Thời gian chạy nhanh, dễ viết và không phụ thuộc vào môi trường bên ngoài.
- Sử dụng mock để giả lập tất cả dependencies.
Ví dụ: Kiểm tra UsersService
hoạt động đúng khi sử dụng repository đã được mock.
typescript
describe('UsersService', () => {
let service: UsersService;
let mockRepository: Partial<UsersRepository>;
beforeEach(() => {
mockRepository = {
findById: jest.fn((id) => `Mocked User ${id}`),
};
service = new UsersService(mockRepository as UsersRepository);
});
it('should return user by ID', () => {
const result = service.getUserById(1);
expect(result).toBe('Mocked User 1');
expect(mockRepository.findById).toHaveBeenCalledWith(1);
});
});
2. Kiểm Tra Tích Hợp (Integration Test)
- Mục tiêu: Đảm bảo sự tương tác chính xác giữa các thành phần trong module như controller, service và repository.
- Phạm vi: Kiểm tra nhiều thành phần hoạt động cùng nhau mà không cần kết nối cơ sở dữ liệu thực.
- Đặc điểm:
- Một số dependencies được sử dụng thực tế, một số có thể được mock.
- Đảm bảo các thành phần tích hợp đúng cách.
Ví dụ: Kiểm tra UsersController
trả về đúng dữ liệu khi gọi UsersService
.
typescript
describe('UsersController', () => {
let controller: UsersController;
let service: UsersService;
beforeEach(async () => {
const module = await Test.createTestingModule({
controllers: [UsersController],
providers: [UsersService, UsersRepository],
}).compile();
controller = module.get<UsersController>(UsersController);
service = module.get<UsersService>(UsersService);
});
it('should return user by ID', async () => {
jest.spyOn(service, 'getUserById').mockResolvedValue('User 1');
const result = await controller.getUserById(1);
expect(result).toBe('User 1');
});
});
3. Kiểm Tra Toàn Diện (End-to-End Test)
- Mục tiêu: Kiểm tra toàn bộ quá trình của ứng dụng từ client đến server, bao gồm cả cơ sở dữ liệu.
- Phạm vi: Tập trung vào việc kiểm tra hệ thống như một ứng dụng hoàn chỉnh.
- Đặc điểm:
- Không mock bất kỳ thành phần nào.
- Cần môi trường thực tế như server chạy và kết nối cơ sở dữ liệu.
- Thời gian chạy chậm hơn nhưng đảm bảo rằng toàn bộ ứng dụng hoạt động chính xác.
Ví dụ: Kiểm tra API /users/:id
trả về đúng dữ liệu từ database.
typescript
import * as request from 'supertest';
describe('Users (e2e)', () => {
let app: INestApplication;
beforeAll(async () => {
const module = await Test.createTestingModule({
imports: [UsersModule],
}).compile();
app = module.createNestApplication();
await app.init();
});
it('GET /users/:id', async () => {
const response = await request(app.getHttpServer())
.get('/users/1')
.expect(200);
expect(response.body).toEqual({ id: 1, name: 'User 1' });
});
afterAll(async () => {
await app.close();
});
});
So Sánh giữa Ba Loại Kiểm Tra
Tiêu chí | Kiểm Tra Đơn Vị | Kiểm Tra Tích Hợp | Kiểm Tra Toàn Diện |
---|---|---|---|
Mục tiêu | Kiểm tra logic từng thành phần | Kiểm tra sự tương tác giữa các thành phần | Kiểm tra toàn bộ ứng dụng |
Phạm vi | Rất nhỏ (một class hoặc function) | Module hoặc nhóm component | Hệ thống hoàn chỉnh |
Dependencies | Được mock hoàn toàn | Một số thực, một số mock | Sử dụng thực tế |
Tốc độ | Nhanh | Trung bình | Chậm |
Độ phức tạp | Thấp | Trung bình | Cao |
Khi nào sử dụng? | Kiểm tra logic cụ thể và nhanh chóng | Kiểm tra tích hợp giữa các thành phần | Kiểm tra toàn bộ hệ thống |
Khi Nào Nên Sử Dụng Loại Kiểm Tra Nào?
-
Kiểm Tra Đơn Vị:
- Sử dụng để kiểm tra logic cụ thể như tính toán, xử lý dữ liệu.
- Nên được sử dụng thường xuyên vì tính nhanh chóng và dễ dàng viết.
-
Kiểm Tra Tích Hợp:
- Đảm bảo rằng các thành phần hoạt động đúng khi tích hợp với nhau.
- Thường được viết cho controller nhằm kiểm tra toàn bộ logic của module.
-
Kiểm Tra Toàn Diện:
- Sử dụng để kiểm tra hệ thống thực tế trước khi phát hành.
- Nên dùng ít hơn do thời gian chạy lâu và yêu cầu môi trường phức tạp.
Kết Luận
- Kiểm Tra Đơn Vị: Tập trung vào việc kiểm tra logic nhỏ và đơn giản.
- Kiểm Tra Tích Hợp: Đảm bảo các module hoạt động đúng với nhau.
- Kiểm Tra Toàn Diện: Đảm bảo toàn bộ hệ thống hoạt động hiệu quả mà không có lỗi nghiêm trọng.
Sự kết hợp hợp lý cả ba loại kiểm tra này sẽ giúp nâng cao chất lượng và độ tin cậy cho ứng dụng NestJS của bạn.
Liên Quan
[NestJS Testing là gì ? Một cách để đảm bảo ứng dụng chạy hiệu quả]
#nestjs #testing #backend
source: viblo