Testing is essential for maintaining code quality and preventing regressions. Here's a comprehensive approach to testing JavaScript applications.
Test individual functions or components in isolation:
// utils.js
export const calculateTotal = (items) => {
return items.reduce((sum, item) => sum + item.price, 0);
};
// utils.test.js
import { calculateTotal } from './utils';
describe('calculateTotal', () => {
it('should calculate total price correctly', () => {
const items = [
{ price: 10 },
{ price: 20 },
{ price: 30 }
];
expect(calculateTotal(items)).toBe(60);
});
it('should handle empty array', () => {
expect(calculateTotal([])).toBe(0);
});
});
Test how different parts work together:
// api.test.js
import { fetchUserData } from './api';
import { formatUserProfile } from './utils';
describe('User data flow', () => {
it('should fetch and format user data', async () => {
const userData = await fetchUserData(1);
const profile = formatUserProfile(userData);
expect(profile).toHaveProperty('displayName');
expect(profile).toHaveProperty('email');
});
});
The most popular JavaScript testing framework:
// jest.config.js
module.exports = {
testEnvironment: 'jsdom',
setupFilesAfterEnv: ['<rootDir>/src/setupTests.js'],
moduleNameMapping: {
'^@/(.*)$': '<rootDir>/src/$1'
}
};
For testing React components:
import { render, screen, fireEvent } from '@testing-library/react';
import LoginForm from './LoginForm';
test('should submit form with correct data', () => {
render(<LoginForm onSubmit={mockSubmit} />);
fireEvent.change(screen.getByLabelText('Email'), {
target: { value: 'test@example.com' }
});
fireEvent.click(screen.getByRole('button', { name: 'Login' }));
expect(mockSubmit).toHaveBeenCalledWith({
email: 'test@example.com'
});
});
// Testing async functions
test('should handle async operations', async () => {
const data = await fetchData();
expect(data).toBeDefined();
});
// Testing with fake timers
test('should debounce function calls', () => {
jest.useFakeTimers();
const mockFn = jest.fn();
const debouncedFn = debounce(mockFn, 1000);
debouncedFn();
debouncedFn();
debouncedFn();
jest.runAllTimers();
expect(mockFn).toHaveBeenCalledTimes(1);
});
This builds on fundamentals and async-programming concepts.
For React-specific testing, see react/component-patterns.
Backend testing patterns are covered in backend/api-design.
#javascript #testing #jest #quality