Unit Test Xử Lý Tệp Trong Node.js Với Jest: Tránh Ô Nhiễm Đĩa & Rò Rỉ I/O
Chiến lược viết unit test cho các hàm đọc, ghi và xử lý tệp trong Node.js sử dụng Jest, Buffer ảo và kỹ thuật mock module an toàn.
Kiểm thử đơn vị code đọc, ghi, chuyển đổi hoặc xác thực tệp trong Node.js đòi hỏi sự cô lập cẩn thận để ngăn chặn ô nhiễm dữ liệu kiểm thử, I/O chậm và lỗi đường dẫn phụ thuộc nền tảng. Dưới đây là các chiến lược thực tiễn để kiểm thử logic tệp với Jest.
Kiểm Thử Xử Lý Buffer Và Stream
Khi kiểm thử đơn vị các bộ phân tích hoặc chuyển đổi tệp, hãy tránh đọc từ filesystem vật lý. Truyền trực tiếp Buffer trong bộ nhớ hoặc Readable stream.
import { parseCsvBuffer } from '../src/csvParser';
describe('Unit Test Xử Lý CSV', () => {
it('phân tích dữ liệu CSV hợp lệ thành các bản ghi có cấu trúc', async () => {
const mockCsvContent = 'id,name,role\n1,Alice,Admin\n2,Bob,Developer';
const buffer = Buffer.from(mockCsvContent, 'utf-8');
const result = await parseCsvBuffer(buffer);
expect(result).toHaveLength(2);
expect(result[0]).toEqual({ id: '1', name: 'Alice', role: 'Admin' });
});
it('ném ValidationError khi buffer rỗng', async () => {
const emptyBuffer = Buffer.alloc(0);
await expect(parseCsvBuffer(emptyBuffer)).rejects.toThrow('File cannot be empty');
});
});
Tải bộ dữ liệu CSV mẫu 1MB có cấu trúc với hơn 10.000 dòng để benchmark bộ phân tích của bạn.
Tải File Mẫu 1MB CSV →Mock Module fs/promises Của Node.js
Đối với các hàm tương tác trực tiếp với đĩa, sử dụng khả năng mock module của Jest:
import * as fs from 'fs/promises';
import { readConfigSafely } from '../src/fileConfig';
jest.mock('fs/promises');
describe('readConfigSafely', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('trả về cấu hình đã phân tích khi tệp tồn tại', async () => {
(fs.readFile as jest.Mock).mockResolvedValue(JSON.stringify({ maxUploadSize: 10485760 }));
const config = await readConfigSafely('/etc/app/config.json');
expect(config.maxUploadSize).toBe(10485760);
expect(fs.readFile).toHaveBeenCalledWith('/etc/app/config.json', 'utf-8');
});
});
Các Quy Tắc Tốt Nhất Cho Unit Test Tệp
- Không commit binary lớn vào git: Giữ các tệp fixture kiểm thử nhỏ (<50KB) hoặc tạo chúng theo cách xác định.
- Sử dụng thư mục tạm: Khi không thể tránh ghi đĩa, ghi vào
os.tmpdir()và dọn sạch trongafterAll. - Kiểm tra tính toàn vẹn nhị phân: Sử dụng so sánh checksum để xác nhận các bộ chuyển đổi tệp xuất ra nội dung hợp lệ.
Nguyễn Đại Long
Tác GiảBackend Lead • Chuyên gia Kiến trúc Hệ thống Phân tán & Lưu trữ Đám mây
Hơn 4 năm kinh nghiệm thiết kế các hệ thống xử lý tệp tải lên thông lượng lớn, tối ưu hóa cơ sở dữ liệu và hạ tầng phân tán Cloudflare R2 / AWS S3. Người sáng lập FileDummy và Mạng lưới Hệ sinh thái NDL.
Bài viết này có hữu ích không?
Bấm Thích để ủng hộ tác giả và giúp bài viết lan tỏa tới cộng đồng lập trình viên.
Thảo Luận Kỹ Thuật & Đóng Góp Ý Kiến (0)
Chia sẻ kết quả benchmark, phản hồi các trường hợp biên hoặc đặt câu hỏi chuyên môn.
Chưa có bình luận nào. Hãy là lập trình viên đầu tiên bắt đầu cuộc thảo luận!
Câu Hỏi Thường Gặp (FAQ)
What is memfs and why use it instead of real files?▾
memfs is an in-memory Node.js fs implementation. Tests run faster with no disk I/O, no temp files to clean up, and reproducible state that resets between tests. It is ideal for unit testing file-reading and writing code.
How do I use memfs to mock the fs module in Jest?▾
Create __mocks__/fs.js that exports memfs. Jest automatically replaces require('fs') with your mock when jest.mock('fs') is called. For ESM use jest.unstable_mockModule('node:fs', ...) or the fs/promises mock.
How do I test a function that reads a large file as a stream?▾
Create a memfs virtual file with vol.writeFileSync() and any content. memfs implements createReadStream compatible with Node.js stream interfaces, so pipe it through your function normally.