Skip to content

Instantly share code, notes, and snippets.

@alisherafat01
Last active April 21, 2025 11:22
Show Gist options
  • Save alisherafat01/072400786e475dd60411beef319b05c7 to your computer and use it in GitHub Desktop.
Save alisherafat01/072400786e475dd60411beef319b05c7 to your computer and use it in GitHub Desktop.
πŸ” Test Behavior, Not Implementation
import React, { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h2 data-testid="counter-value">{count}</h2>
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
}
import { render, screen, fireEvent } from '@testing-library/react';
import Counter from './Counter';
test('BAD: test internal state update (implementation)', () => {
const { container } = render(<Counter />);
// This depends too much on structure of implementation
const button = container.querySelector('button');
fireEvent.click(button);
fireEvent.click(button);
// Directly assuming the heading is second child = fragile
expect(container.querySelector('h2').textContent).toBe('2');
});
test('GOOD: test visible behavior like a user would', () => {
render(<Counter />);
// use regex or test-id to get elements that don't rely on specific implemntation
const button = screen.getByText(/increase/i);
const value = screen.getByTestId('counter-value');
// test bahavior
expect(value).toHaveTextContent('0');
fireEvent.click(button);
fireEvent.click(button);
expect(value).toHaveTextContent('2');
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment