Testing is a crucial part of software development that ensures your code works as expected. Let's explore unit and integration testing through a practical to-do list example.
Unit Testing
Unit tests focus on testing individual components or functions in isolation.
React Example (Jest)
// TodoItem.test.js
describe('TodoItem', () => {
it('renders todo text correctly', () => {
render(<TodoItem text="Buy groceries" />);
expect(screen.getByText('Buy groceries')).toBeInTheDocument();
});
it('calls onToggle when clicked', () => {
const onToggle = jest.fn();
render(<TodoItem text="Test" onToggle={onToggle} />);
fireEvent.click(screen.getByRole('checkbox'));
expect(onToggle).toHaveBeenCalled();
});
});
Rails Example (RSpec)
# spec/models/todo_spec.rb
RSpec.describe Todo, type: :model do
it 'is valid with a title' do
todo = Todo.new(title: 'Buy groceries')
expect(todo).to be_valid
end
it 'is invalid without a title' do
todo = Todo.new(title: nil)
expect(todo).not_to be_valid
end
end
Integration Testing
Integration tests verify that different parts of your application work together correctly.
Testing the Full Flow
Integration tests would verify that:
- A user can create a new todo
- The todo appears in the list
- The todo can be marked as complete
- The todo can be deleted
This ensures all components - frontend, backend, and database - work together seamlessly.