对于 contentEditable 元素,在 "onInput" 上未实现要调用的 Expect 方法
Expect method to have been called is not fulfilled on "onInput" for a contentEditable element
我有一个使用 contentEditable
作为输入法的组件。组件中感兴趣的部分是:
<div className="enter-edit-mode" onClick={view.enterEditMode}>
<div className="user-input" ref="content" contentEditable onInput={view.textChanged}></div>
</div>
该组件工作正常 - 它根据用户输入进入 textChanged
方法。该方法如下所示:
textChanged: function (e) {
var view = this,
textValue = e.target.innerHTML;
view.setState({
enteringText: textValue.length,
temporaryValue: textValue
});
}
我遇到的问题 在我尝试测试输入行为时出现。使用 enzyme、chai、sinon 完成设置。我正在使用一个简单的 renderComponent
函数渲染组件,使用酶的 mount
方法。
beforeEach(function () {
view = renderComponent(card);
viewReact = view.get(0);
});
it('should enter text changed method on input', function () {
let spy = sinon.spy(viewReact, 'textChanged');
view.find('.user-input').simulate('input');
expect(spy).to.have.been.called;
spy.restore();
});
它输出 expected textChanged 至少被调用一次,但从未被调用。 但是,奇怪的部分 是,如果我在组件的方法中放置一个 console.log
,它就会到达那里。
我努力让它发挥作用
- 使用
sinon.stub
而不是 spy
,因为我认为可能我的方法中的某些内容无法正常工作
- 用
view.find('.user-input').simulate('input', {target: {value: "lorem"})
或.simulate('input', {key: 'a'})
调用
如果我不模拟输入而是 viewReact.textChanged()
,它显然有效。
我猜这是 contentEditable 上的输入法导致的。有什么建议么?如何在 onInput
方法中正确输入文本? (即使在textChanged
方法中获取,文本为空)
我做了一点测试,我没有 sinon 但我找到了一个用例:
class Home extends Component {
state = {
status: 'default'
}
textChanged = () => {
this.setState({
status: 'changed'
})
}
render () {
return (
<div className="enter-edit-mode" >
<div className="user-input" ref="content" contentEditable onInput={this.textChanged}>Hello</div>
<span>{this.state.status}</span>
</div>
)
}
}
和测试
describe('component', () => {
it('should say changed', () => {
const component = shallow(<Home />);
expect(component.find('span').text()).toEqual('default');
component.find('.user-input').simulate('input', {key: 'a'})
expect(component.find('span').text()).toEqual('changed');
});
});
一切如期而至
我可以通过测试以下组件(看起来与您的类似)重现您的问题:
const MyComponent = React.createClass({
textChanged(e) { console.log('text changed') },
render() {
return (
<div className="enter-edit-mode">
<div className="user-input" ref="content" contentEditable onInput={ this.textChanged }></div>
</div>
);
}
});
我还设法以一种有点复杂的方式进行了测试:
it('should enter text changed method on input', () => {
let view = mount(<MyComponent/>);
let spy = sinon.spy(view.instance(), 'textChanged');
view = view.mount();
view.find('.user-input').simulate('input');
expect(spy).to.be.called;
spy.restore();
});
view.mount()
到 re-mount 组件似乎可以解决这个问题。
我对 Enzyme 一点都不熟悉(虽然我喜欢它:),但看起来它在组件周围添加了各种层,在这种情况下 Sinon 间谍很容易得到 "lost" .
一个可能的警告:我使用 jsdom
在 Node 中完成了所有这些测试,而不是在浏览器中。
我有一个使用 contentEditable
作为输入法的组件。组件中感兴趣的部分是:
<div className="enter-edit-mode" onClick={view.enterEditMode}>
<div className="user-input" ref="content" contentEditable onInput={view.textChanged}></div>
</div>
该组件工作正常 - 它根据用户输入进入 textChanged
方法。该方法如下所示:
textChanged: function (e) {
var view = this,
textValue = e.target.innerHTML;
view.setState({
enteringText: textValue.length,
temporaryValue: textValue
});
}
我遇到的问题 在我尝试测试输入行为时出现。使用 enzyme、chai、sinon 完成设置。我正在使用一个简单的 renderComponent
函数渲染组件,使用酶的 mount
方法。
beforeEach(function () {
view = renderComponent(card);
viewReact = view.get(0);
});
it('should enter text changed method on input', function () {
let spy = sinon.spy(viewReact, 'textChanged');
view.find('.user-input').simulate('input');
expect(spy).to.have.been.called;
spy.restore();
});
它输出 expected textChanged 至少被调用一次,但从未被调用。 但是,奇怪的部分 是,如果我在组件的方法中放置一个 console.log
,它就会到达那里。
我努力让它发挥作用
- 使用
sinon.stub
而不是spy
,因为我认为可能我的方法中的某些内容无法正常工作 - 用
view.find('.user-input').simulate('input', {target: {value: "lorem"})
或.simulate('input', {key: 'a'})
调用
如果我不模拟输入而是 viewReact.textChanged()
,它显然有效。
我猜这是 contentEditable 上的输入法导致的。有什么建议么?如何在 onInput
方法中正确输入文本? (即使在textChanged
方法中获取,文本为空)
我做了一点测试,我没有 sinon 但我找到了一个用例:
class Home extends Component {
state = {
status: 'default'
}
textChanged = () => {
this.setState({
status: 'changed'
})
}
render () {
return (
<div className="enter-edit-mode" >
<div className="user-input" ref="content" contentEditable onInput={this.textChanged}>Hello</div>
<span>{this.state.status}</span>
</div>
)
}
}
和测试
describe('component', () => {
it('should say changed', () => {
const component = shallow(<Home />);
expect(component.find('span').text()).toEqual('default');
component.find('.user-input').simulate('input', {key: 'a'})
expect(component.find('span').text()).toEqual('changed');
});
});
一切如期而至
我可以通过测试以下组件(看起来与您的类似)重现您的问题:
const MyComponent = React.createClass({
textChanged(e) { console.log('text changed') },
render() {
return (
<div className="enter-edit-mode">
<div className="user-input" ref="content" contentEditable onInput={ this.textChanged }></div>
</div>
);
}
});
我还设法以一种有点复杂的方式进行了测试:
it('should enter text changed method on input', () => {
let view = mount(<MyComponent/>);
let spy = sinon.spy(view.instance(), 'textChanged');
view = view.mount();
view.find('.user-input').simulate('input');
expect(spy).to.be.called;
spy.restore();
});
view.mount()
到 re-mount 组件似乎可以解决这个问题。
我对 Enzyme 一点都不熟悉(虽然我喜欢它:),但看起来它在组件周围添加了各种层,在这种情况下 Sinon 间谍很容易得到 "lost" .
一个可能的警告:我使用 jsdom
在 Node 中完成了所有这些测试,而不是在浏览器中。