Флажок не "проверен" после имитации "изменения" с ферментом
Я попытался использовать фермент для имитации события change
на флажке и использовать chai-enzyme
для подтверждения, если он был отмечен.
Это мой реактивный компонент Hello
:
import React from 'react';
class Hello extends React.Component {
constructor(props) {
super(props);
this.state = {
checked: false
}
}
render() {
const {checked} = this.state;
return <div>
<input type="checkbox" defaultChecked={checked} onChange={this._toggle.bind(this)}/>
{
checked ? "checked" : "not checked"
}
</div>
}
_toggle() {
const {onToggle} = this.props;
this.setState({checked: !this.state.checked});
onToggle();
}
}
export default Hello;
И мой тест:
import React from "react";
import Hello from "../src/hello.jsx";
import chai from "chai";
import {mount} from "enzyme";
import chaiEnzyme from "chai-enzyme";
import jsdomGlobal from "jsdom-global";
import spies from 'chai-spies';
function myAwesomeDebug(wrapper) {
let html = wrapper.html();
console.log(html);
return html
}
jsdomGlobal();
chai.should();
chai.use(spies);
chai.use(chaiEnzyme(myAwesomeDebug));
describe('<Hello />', () => {
it('checks the checkbox', () => {
const onToggle = chai.spy();
const wrapper = mount(<Hello onToggle={onToggle}/>);
var checkbox = wrapper.find('input');
checkbox.should.not.be.checked();
checkbox.simulate('change', {target: {checked: true}});
onToggle.should.have.been.called.once();
console.log(checkbox.get(0).checked);
checkbox.should.be.checked();
});
});
Когда я запускаю этот тест, checkbox.get(0).checked
равен false
, а утверждение checkbox.should.be.checked()
сообщает об ошибке:
AssertionError: expected the node in <Hello /> to be checked <input type="checkbox" checked="checked">
Вы можете видеть, что сообщение довольно странное, поскольку на выходе уже есть checked="checked"
.
Я не уверен, где что-то не так, поскольку в нем слишком много вещей.
Вы также можете увидеть демонстрационный проект здесь: https://github.com/js-demos/react-enzyme-simulate-checkbox-events-demo, обратите внимание на эти строки
Ответы
Ответ 1
Я думаю, что некоторые детали моего объяснения могут быть немного неправильными, но я понимаю:
Когда вы делаете
var checkbox = wrapper.find('input');
Сохраняет ссылку на этот Enzyme node в checkbox
, но бывают случаи, когда дерево Enzyme обновляется, а checkbox
- нет. Я не знаю, связано ли это с тем, что ссылка в дереве изменяется, и поэтому checkbox
теперь является ссылкой на node в старой версии дерева.
Выполнение функции checkbox
, похоже, заставляет ее работать для меня, потому что теперь значение checkbox()
всегда берется из самого последнего дерева.
var checkbox = () => wrapper.find('input');
checkbox().should.not.be.checked();
checkbox().simulate('change', {target: {checked: true}});
///...
Ответ 2
Это не ошибка, а "работает как задумано".
Основной фермент использует утилиту тестирования реакции для взаимодействия с реакцией, особенно с имитацией API.
Simulate на самом деле не обновляет dom, он просто запускает обработчики событий, прикрепленные к компоненту, возможно, с дополнительными параметрами, которые вы передаете.
Согласно полученному здесь ответу (https://github.com/facebook/react/issues/4950), это связано с тем, что обновление dom потребовало бы от React переопределить многие функции браузера, что, вероятно, по-прежнему приводило к непредвиденным действиям, поэтому они решили просто положиться на браузер для выполнения обновления..
Единственный способ проверить это - вручную обновить dom и вызвать API-интерфейс имитации.