这是我的组件:
class App extends Component {
constructor(props) {
super(props);
this.state = {
value: 'foo'
};
}
onChange = (e) => {
this.setState({
value: e.currentTarget.value
});
};
render() {
return (
<div className="App">
<input
id="foo"
value={this.state.value}
onChange={this.onChange}
/>
</div>
);
}
}
这是我的测试:
import {shallow, mount} from 'enzyme';
it('fires onChange', () => {
let wrapper = mount(<App />);
wrapper.find('#foo').simulate('change', {currentTarget: {value: 'bar'}});
expect(wrapper.state().value).toBe('bar');
expect(wrapper.find('#foo').props().value).toBe('bar');
});
目前测试失败了:
Expected value to be (using ===):
"bar"
Received:
"foo"
但如果我将mount
更改为shallow
,它就会通过。我不完全确定为什么,而且我想知道浅层渲染和装载渲染之间是否存在任何其他实际差异。
答案 0 :(得分:0)
要修复测试,您可以尝试:
import { mount } from 'enzyme';
it('fires onChange', () => {
const wrapper = mount(<App />).find('#foo');
expect(wrapper.props().value).toBe('foo');
wrapper.props().onChange({ currentTarget: { value: 'bar' } });
expect(wrapper.props().value).toBe('bar');
});
澄清浅层,山脉和酶的差异
<强>浅强>
真实单元测试(隔离,无子渲染)
简单浅
呼叫:
浅层+ setProps
呼叫:
浅层+卸载
呼叫:
<强>挂载强>
测试componentDidMount和componentDidUpdate的唯一方法。完整渲染包括子组件。需要DOM(jsdom,domino)。执行时间更长。如果在JSDOM之前包含react,则可能需要一些技巧:
`require('fbjs / lib / ExecutionEnvironment')。canUseDOM = true;
简单装载
呼叫:
装载+ setProps
呼叫:
装载+卸载
呼叫:
<强>渲染强>
只调用渲染但渲染所有子渲染。
所以我的经验法则是:
似乎有一个非常小的渲染用例。我喜欢它,因为它似乎比要求jsdom更快,但正如@ljharb所说,我们无法用它来测试React内部。
我想知道是否可以使用render方法模拟生命周期方法,就像浅层一样?如果你能给我内部渲染的用例或你在野外看到的用例,我将非常感激。
我也很想知道为什么浅不调用componentDidUpdate。
Kudos转到https://gist.github.com/fokusferit/e4558d384e4e9cab95d04e5f35d4f913和https://github.com/airbnb/enzyme/issues/465#issuecomment-227697726这基本上是问题评论的副本