Jest là một thư viện kiểm thử phổ biến được phát triển bởi Facebook, giúp bạn kiểm tra các ứng dụng ReactJS của mình một cách hiệu quả. Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách sử dụng Jest để kiểm thử ứng dụng ReactJS của bạn.
Bước 1: Cài đặt Jest và các gói phụ thuộc
Đầu tiên, bạn cần cài đặt Jest và các gói phụ thuộc liên quan. Chạy các lệnh sau trong terminal của bạn:
npm install --save-dev jest
npm install --save-dev babel-jest @babel/core @babel/preset-env @babel/preset-react
npm install --save-dev react-test-renderer
Điều này sẽ cài đặt Jest, các plugin Babel cần thiết và react-test-renderer, giúp bạn kết xuất các thành phần React trong môi trường kiểm thử.
Bước 2: Cấu hình Babel và Jest
Tạo một tệp .babelrc trong thư mục gốc của dự án của bạn và thêm nội dung sau:
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
Tạo một tệp jest.config.js trong thư mục gốc của dự án và thêm nội dung sau:
module.exports = {
testEnvironment: 'jsdom',
moduleNameMapper: {
'\\.(css|less|sass|scss)$': '<rootDir>/__mocks__/styleMock.js',
'\\.(gif|ttf|eot|svg|png)$': '<rootDir>/__mocks__/fileMock.js'
},
transform: {
'^.+\\.(js|jsx)$': 'babel-jest',
},
moduleFileExtensions: ['js', 'jsx'],
testPathIgnorePatterns: ['/node_modules/'],
};
Đoạn mã trên thiết lập môi trường kiểm thử là jsdom và định nghĩa một số cấu hình như moduleNameMapper và transform.
Tiếp theo, tạo thư mục __mocks__ trong thư mục gốc của dự án và tạo hai tệp sau:
styleMock.js: Để giả lập các tệp CSS, LESS, SASS, SCSS.
fileMock.js: Để giả lập các tệp tài nguyên như hình ảnh và phông chữ.
Thêm nội dung sau vào mỗi tệp:
styleMock.js:
module.exports = {};
fileMock.js:
module.exports = 'test-file-stub';
Bước 3: Viết kiểm thử đơn vị cho thành phần React
Giả sử bạn có một thành phần React tên là Counter trong tệp Counter.js:
import React, { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
const increment = () => {
setCount(count + 1);
};
const decrement = () => {
setCount(count - 1);
};
return (
<div>
<h1>Counter: {count}</h1>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
};
export default Counter;
Để viết các kiểm thử đơn vị cho thành phần này, hãy tạo một tệp kiểm thử mới Counter.test.js trong cùng thư mục với Counter.js. Thêm nội dung sau vào tệp kiểm thử:
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import Counter from './Counter';
describe('Counter', () => {
test('renders the initial count', () => {
const { getByText } = render(<Counter />);
const countElement = getByText(/Counter: 0/i);
expect(countElement).toBeInTheDocument();
});
test('increments the count', () => {
const { getByText } = render(<Counter />);
const incrementButton = getByText('+');
fireEvent.click(incrementButton);
const countElement = getByText(/Counter: 1/i);
expect(countElement).toBeInTheDocument();
});
test('decrements the count', () => {
const { getByText } = render(<Counter />);
const decrementButton = getByText('-');
fireEvent.click(decrementButton);
const countElement = getByText(/Counter: -1/i);
expect(countElement).toBeInTheDocument();
});
});
Trong tệp kiểm thử trên, chúng ta đã sử dụng render và fireEvent từ @testing-library/react để kết xuất và tương tác với thành phần Counter. Sau đó, chúng ta đã viết ba kiểm thử:
Kiểm tra việc hiển thị số đếm ban đầu.
Kiểm tra việc tăng số đếm khi nhấn nút “+”.
Kiểm tra việc giảm số đếm khi nhấn nút “-“.
Bước 4: Chạy các kiểm thử
Để chạy các kiểm thử, bạn cần thêm một script trong tệp package.json của dự án:
"scripts": {
"test": "jest"
}
Giờ đây, bạn có thể chạy các kiểm thử bằng cách sử dụng lệnh sau trong terminal của bạn:
npm test
Kết quả kiểm thử sẽ được hiển thị trong terminal, thông báo cho bạn biết liệu các kiểm thử có thành công hay không.
Bước 5: Kiểm thử thành phần có trạng thái
Giả sử bạn có một thành phần có trạng thái tên là UserList trong tệp UserList.js:
import React, { useState } from 'react';
const UserList = () => {
const [users, setUsers] = useState([]);
const addUser = (name) => {
setUsers([...users, name]);
};
return (
<div>
<ul>
{users.map((user, index) => (
<li key={index}>{user}</li>
))}
</ul>
<button onClick={() => addUser('John Doe')}>Add User</button>
</div>
);
};
export default UserList;
Để kiểm thử thành phần này, tạo một tệp kiểm thử mới UserList.test.js trong cùng thư mục với UserList.js. Thêm nội dung sau vào tệp kiểm thử:
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import UserList from './UserList';
describe('UserList', () => {
test('renders an empty list initially', () => {
const { queryByText } = render(<UserList />);
const userElement = queryByText(/John Doe/i);
expect(userElement).toBeNull();
});
test('adds a user when the button is clicked', () => {
const { getByText, queryByText } = render(<UserList />);
const addButton = getByText(/Add User/i);
fireEvent.click(addButton);
const userElement = queryByText(/John Doe/i);
expect(userElement).toBeInTheDocument();
});
});
Trong tệp kiểm thử trên, chúng ta đã viết hai kiểm thử:
Kiểm tra việc hiển thị danh sách trống ban đầu.
Kiểm tra việc thêm người dùng khi nhấn nút “Add User”.
Bước 6: Kiểm thử tích hợp
Kiểm thử tích hợp là một phần quan trọng trong quá trình kiểm thử ứng dụng ReactJS. Bạn có thể sử dụng thư viện @testing-library/react để kiểm thử tích hợp giữa các thành phần khác nhau.
Giả sử bạn có hai thành phần, ParentComponent và ChildComponent, trong hai tệp riêng biệt ParentComponent.js và ChildComponent.js. ParentComponent sử dụng ChildComponent và truyền một hàm xử lý sự kiện cho nó.
ParentComponent.js:
import React, { useState } from 'react';
import ChildComponent from './ChildComponent';
const ParentComponent = () => {
const [text, setText] = useState('');
const handleButtonClick = () => {
setText('Hello, World!');
};
return (
<div>
<h1>{text}</h1>
<ChildComponent onButtonClick={handleButtonClick} />
</div>
);
};
export default ParentComponent;
ChildComponent.js:
import React from 'react';
const ChildComponent = ({ onButtonClick }) => {
return <button onClick={onButtonClick}>Click me!</button>;
};
export default ChildComponent;
Để kiểm thử tích hợp giữa hai thành phần này, tạo một tệp kiểm thử mới ParentComponent.test.js trong cùng thư mục với ParentComponent.js. Thêm nội dung sau vào tệp kiểm thử:
import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import ParentComponent from './ParentComponent';
describe('ParentComponent', () => {
test('handles child component event', () => {
const { getByText, queryByText } = render(<ParentComponent />);
const buttonElement = getByText(/Click me!/i);
fireEvent.click(buttonElement);
const textElement = queryByText(/Hello, World!/i);
expect(textElement).toBeInTheDocument();
});
});
Trong tệp kiểm thử trên, chúng ta đã kiểm tra việc xử lý sự kiện từ ChildComponent trong ParentComponent. Khi nút “Click me!” được nhấn, chúng ta mong đợi rằng văn bản “Hello, World!” sẽ xuất hiện.
Bước 7: Kiểm thử từ đầu đến cuối (E2E)
Cuối cùng, để đảm bảo ứng dụng của bạn hoạt động đúng như mong đợi trong một môi trường trình duyệt thực tế, bạn nên thực hiện các kiểm thử từ đầu đến cuối (E2E). Bạn có thể sử dụng các công cụ như Cypress hoặc Playwright để kiểm thử E2E cho ứng dụng ReactJS của bạn.
Kết luận
Trong hướng dẫn này, chúng ta đã tìm hiểu cách sử dụng Jest để kiểm thử ứng dụng ReactJS của bạn. Các bước chính bao gồm:
- Cài đặt Jest và các gói phụ thuộc liên quan.
- Cấu hình Babel và Jest cho dự án của bạn.
- Viết và chạy các kiểm thử đơn vị cho các thành phần React.
- Kiểm thử các thành phần có trạng thái.
- Kiểm thử tích hợp giữa các thành phần khác nhau.
- Cuối cùng, nên thực hiện các kiểm thử từ đầu đến cuối (E2E) để đảm bảo ứng dụng hoạt động đúng như mong đợi trong môi trường trình duyệt thực tế.
- Bằng cách sử dụng các công cụ và kỹ thuật này, bạn có thể đảm bảo chất lượng mã nguồn và hành vi của ứng dụng ReactJS của bạn. Điều này sẽ giúp bạn xây dựng ứng dụng ổn định và dễ bảo trì hơn trong tương lai.
Đọc thêm về 10 kỹ năng nâng cao mà các ReactJS developer nào cũng cần phải biết: ReactJS: 10 kỹ năng lập trình nâng cao quan trọng nhất bạn phải biết.

Pingback: Xây dựng ứng dụng chất lượng với kiểm thử đơn vị, tích hợp và toàn diện trong ReactJS - Bệ Phóng Việt