0
0
Lập trình
Harry Tran
Harry Tran106580903228332612117

So Sánh Ba Cơ Chế Kiểm Tra Trong Ứng Dụng NestJS: Unit Test, Integration Test và End-to-End Test

Đăng vào 1 tháng trước

• 5 phút đọc

So Sánh Ba Cơ Chế Kiểm Tra Trong Ứng Dụng NestJS

Chào các bạn! Trong bài viết trước, mình đã cung cấp một cái nhìn tổng quát về các cơ chế kiểm tra trong NestJS. Hôm nay, mình sẽ đi sâu vào ba cơ chế chính: Unit Test, Integration TestEnd-to-End (e2e) Test. Bạn có biết những cơ chế này khác nhau như thế nào và khi nào thì cần sử dụng chúng trong dự án của bạn? Hãy theo dõi bài viết dưới đây nhé!

1. Unit Test

  • Mục tiêu: Kiểm tra logic của từng thành phần riêng lẻ như class, function hoặc module.
  • Phạm vi: Chỉ 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 bên trong của từng thành phần.
    • Thời gian thực hiện 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 các dependencies.
  • Ví dụ: Kiểm tra xem UsersService có hoạt động đúng khi sử dụng repository đã được mock.

Code Ví Dụ:

typescript Copy
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. Integration Test

  • Mục tiêu: Kiểm tra sự tương tá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 cùng hoạt động, thường không bao gồm kết nối cơ sở dữ liệu thực.
  • Đặc điểm:
    • Không mock tất cả dependencies mà sử dụng các phiên bản thực để đảm bảo các thành phần tích hợp đúng cách.
  • Ví dụ: Kiểm tra xem UsersController có trả về đúng dữ liệu khi gọi UsersService.

Code Ví Dụ:

typescript Copy
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. End-to-End (e2e) Test

  • Mục tiêu: Kiểm tra toàn bộ quy trình của ứng dụng từ client đến backend, bao gồm cả cơ sở dữ liệu thực.
  • Phạm vi: Kiểm tra hệ thống như một ứng dụng hoàn chỉnh và toàn diện.
  • Đặc điểm:
    • Không mock bất kỳ thành phần nào, yêu cầu môi trường thực tế, ví dụ: server phải chạy và kết nối cơ sở dữ liệu.
    • Thời gian thực hiện chậm hơn nhưng đảm bảo rằng toàn bộ ứng dụng hoạt động như mong đợi.
  • Ví dụ: Kiểm tra API /users/:id có trả về đúng dữ liệu từ database.

Code Ví Dụ:

typescript Copy
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 Các Cơ Chế Kiểm Tra

Tiêu chí Unit Test Integration Test End-to-End Test
Mục tiêu Kiểm tra logic đơn lẻ Kiểm tra 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 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ể nhanh chóng Đảm bảo các thành phần hoạt động đúng khi tích hợp Kiểm tra toàn bộ hệ thống trước khi phát hành

Khi Nào Nên Sử Dụng Mỗi Loại Test?

  1. Unit Test:

    • Dùng để kiểm tra logic cụ thể (ví dụ: tính toán, xử lý dữ liệu).
    • Thích hợp cho việc viết nhiều lần bởi vì tốc độ thực hiện nhanh và dễ viết.
  2. Integration Test:

    • Đảm bảo rằng các thành phần hoạt động đúng cũng như tích hợp với nhau.
    • Thường được viết cho controller để kiểm tra toàn bộ logic của module.
  3. End-to-End Test:

    • Kiểm tra hệ thống trong môi trường thực tế trước khi phát hành.
    • Sử dụng ít hơn do tốc độ chậm và yêu cầu môi trường phức tạp.

Tóm Lại

  • Unit Tests: Kiểm tra nhanh, tập trung vào logic nhỏ.
  • Integration Tests: Đảm bảo các module hoạt động đúng với nhau.
  • End-to-End Tests: Đảm bảo toàn bộ hệ thống hoàn chỉnh không có lỗi lớn.

Việc kết hợp hợp lý cả ba loại kiểm tra sẽ giúp đảm bảo chất lượng cao nhất cho ứng dụng của bạn và giúp bạn phát hiện lỗi sớm hơn trong quá trình phát triển.

Liên Quan

[Thông tin thêm về NestJS Testing] (https://chatgpt.com/share/67775eed-5a40-8013-b24c-73a7c4bc13be) - Bạn có thể theo dõi bài viết gốc của mình tại đây: NestJS Testing cơ bản #nestjs #testing #backend
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào