Как я могу вызвать изменение состояния в модульном тесте с React DOM?
Я использую React Test Utilities для модульного тестирования моего кода. Я звоню renderIntoDocument
визуализировать пользовательский компонент, а затем использовать findDOMNode
чтобы проверить, что получилось. Проблема, с которой я сталкиваюсь, заключается в том, что я не уверен, как обновить состояние и эффективно запустить повторную визуализацию в контексте модульного теста.
Вот пример кода - обратите внимание на комментарий к коду:
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-dom/test-utils';
import MyCustomComponent from '../../app/components/MyCustomComponent';
describe('My Test Suite', () => {
let component, node;
test('verify state change', () => {
const items = [{'value': '1'}];
component = TestUtils.renderIntoDocument(
<MyCustomComponent items={items} />
);
node = ReactDOM.findDOMNode(component);
expect(node.querySelector('input[type=text]').value).toEqual('1');
component.state.items = [{'value': '2'}];
// do something here to trigger a re-render?
expect(node.querySelector('input[type=text]').value).toEqual('2');
});
});
К сожалению, кажется, что просто изменение переменной состояния ничего не делает. И я не могу позвонить component.componentWillReceiveProps()
потому что это, кажется, не определено.
Обратите внимание, что я хочу, чтобы тот же компонент вызывал свою функцию рендеринга, а не заменял ее фактически новым компонентом. Причина в том, что я нашел ошибку, когда компонент рендерил вещи на основе this.props
вместо this.state
и я хочу, чтобы тест показал, что он всегда использует данные из состояния, а не из начальных значений.
1 ответ
Фермент от AirBnb имеет несколько полезных утилит для этого. Вам нужно будет установить зависимости, но это достаточно просто настроить. Затем вы можете просто позвонить ферменту setState
метод на вашем экземпляре компонента. Важное замечание - ваш "экземпляр компонента" в данном случае является мелко визуализированным компонентом. Ваш код будет выглядеть примерно так:
import React from 'react';
import MyCustomComponent from '../../app/components/MyCustomComponent';
import { shallow, configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// configure your adapter
configure({ adapter: new Adapter() });
describe('My Test Suite', () => {
test('verify state change', () => {
const items = [{'value': '1'}];
const wrapper = shallow(<MyCustomComponent items={items} />);
// find your shallow rendered component and check its value
expect(wrapper.find('input[type="text"]').value).toEqual('1');
// set the state of the component
wrapper.setState({ items: [{'value': '2'}] });
// state should be updated, make sure its value was properly set
expect(wrapper.find('input[type="text"]').value).toEqual('2');
});
});
Все это предполагает, что вы используете state
в вашем компоненте правильно. В твоем случае, items
кажется, передается как prop
, Если вы устанавливаете state
просто копируя props
Вы можете пересмотреть свою стратегию. В любом случае этот подход должен быть идентичен тому, как state
обновления в React работают - вы работаете с одним экземпляром компонента, не отключая и не монтируя компонент. Надеюсь это поможет.