Enzyme предоставляет три основных метода рендеринга компонентов для тестирования, каждый из которых подходит для разных сценариев.
Прежде чем начать, установите необходимые пакеты:
npm install enzyme enzyme-adapter-react-16 react-test-renderer
Создайте файл конфигурации setupTests.js
:
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
Используется для изолированного тестирования компонентов без рендеринга дочерних компонентов.
import { shallow } from 'enzyme';
const Button = ({ children, onClick }) => (
<button onClick={onClick} className="btn">
{children}
</button>
);
describe('Button Component', () => {
it('renders children correctly', () => {
const wrapper = shallow(<Button>Click me</Button>);
expect(wrapper.find('.btn').text()).toEqual('Click me');
});
it('calls onClick handler when clicked', () => {
const mockClick = jest.fn();
const wrapper = shallow(<Button onClick={mockClick}>Click</Button>);
wrapper.find('.btn').simulate('click');
expect(mockClick).toHaveBeenCalledTimes(1);
});
});
Необходим для тестирования компонентов с жизненным циклом (lifecycle) или интеграции с DOM API.
import { mount } from 'enzyme';
class Counter extends React.Component {
state = { count: 0 };
increment = () => this.setState({ count: this.state.count + 1 });
render() {
return (
<div>
<span className="count-value">{this.state.count}</span>
<button className="increment-btn" onClick={this.increment}>
Increment
</button>
</div>
);
}
}
describe('Counter Component', () => {
it('increments count when button is clicked', () => {
const wrapper = mount(<Counter />);
expect(wrapper.find('.count-value').text()).toBe('0');
wrapper.find('.increment-btn').simulate('click');
expect(wrapper.find('.count-value').text()).toBe('1');
});
it('calls componentDidMount', () => {
jest.spyOn(Counter.prototype, 'componentDidMount');
mount(<Counter />);
expect(Counter.prototype.componentDidMount).toHaveBeenCalledTimes(1);
});
});
Используется для анализа итогового HTML-вывода.
import { render } from 'enzyme';
const Message = ({ text }) => <div className="message">{text}</div>;
describe('Message Component', () => {
it('renders correct message', () => {
const wrapper = render(<Message text="Hello World" />);
expect(wrapper.find('.message').text()).toBe('Hello World');
});
});
Пример тестирования компонента с хуками:
function useCounter(initialValue = 0) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(count + 1);
return { count, increment };
}
const Counter = () => {
const { count, increment } = useCounter();
return (
<div>
<span data-testid="count">{count}</span>
<button onClick={increment}>+</button>
</div>
);
};
describe('Counter with Hooks', () => {
it('should increment counter', () => {
const wrapper = mount(<Counter />);
expect(wrapper.find('[data-testid="count"]').text()).toBe('0');
wrapper.find('button').simulate('click');
expect(wrapper.find('[data-testid="count"]').text()).toBe('1');
});
});
const ThemeContext = React.createContext('light');
const ThemedButton = () => (
<ThemeContext.Consumer>
{theme => <button className={`btn-${theme}`}>Button</button>}
</ThemeContext.Consumer>
);
describe('ThemedButton', () => {
it('renders with light theme by default', () => {
const wrapper = shallow(<ThemedButton />);
expect(wrapper.find('.btn-light')).toHaveLength(1);
});
it('renders with dark theme when provided', () => {
const wrapper = mount(
<ThemeContext.Provider value="dark">
<ThemedButton />
</ThemeContext.Provider>
);
expect(wrapper.find('.btn-dark')).toHaveLength(1);
});
});
Используйте правильный метод рендеринга:
shallow
для изолированных юнит-тестовmount
для интеграционных тестовrender
для проверки HTML-выводаИзбегайте тестирования реализации:
Используйте матчеры Jest:
expect(wrapper.find('.item')).toHaveLength(3);
expect(wrapper.props().disabled).toBeTruthy();
Enzyme предоставляет мощный инструментарий для тестирования React-компонентов на разных уровнях. Выбирая между shallow, mount и render, вы можете контролировать глубину тестирования. Хотя современные проекты чаще используют React Testing Library, Enzyme остается отличным выбором для комплексного тестирования, особенно в legacy-проектах.