【发布时间】:2018-03-01 17:56:35
【问题描述】:
我有这个组件(简化版):
export default class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
data: {}
};
}
componentDidUpdate(prevProps, prevState) {
if(this.props.time && this.props.time !== prevProps.time){
this.setState({
isLoading: true
})
fetch(...).then(data => {
this.setState({
data: data
isLoading:false
}
}
}
render(){
{isLoading, data} = this.state;
return (isLoading ? /*show spinner*/ : /* show data*/);
}
}
这个组件工作:它在获取数据时显示一个微调器,然后显示数据。
我正在尝试使用玩笑和酶来测试它:
test('Mounted correctly', async() => {
let myComponent = mount(<MyComponent time='01-01-18'/>);
myComponent.setProps({time: '02-01-18'}); //necessary to call componentDidUpdate
expect(myComponent.state()).toMatchSnapshot();
}
据我所知,要拨打componentDidUpdate您必须拨打setPros (link)。但是,在调试器之后,点击时调用结束:
this.setState({
isLoading: true
})
这有点出乎意料,问题是快照是:
Object {
"isLoading": true
"data": {}
}
这当然是我不想要的。我该如何解决这个问题?
更新:我找到了一个(n 丑陋的)解决方案!
问题是我们要测试的是这个setState完成了:
this.setState({
data: data
isLoading:false
}
现在,即使设置 await myComponent.setProps({time: '02-01-18'});(如其中一个答案中所建议的那样)也不会发生这种情况,因为它不会等待上述 setState 创建的新异步调用。
我找到的唯一解决方案是将回调函数传递给props,并在setState 完成后调用它。回调函数包含我们想要的expect!
所以这是最终的结果:
test('Mounted correctly', async() => {
let myComponent = mount(<MyComponent time='01-01-18'/>);
const callBackAfterLastSetStateIsCompleted = () => {
expect(topAsins.state()).toMatchSnapshot();
}
myComponent.setProps({time: '02-01-18', testCallBack: callBackAfterLastSetStateIsCompleted}); //necessary to call componentDidUpdate
expect(myComponent.state()).toMatchSnapshot();
}
并将组件代码修改为:
this.setState({
data: data
isLoading:false
},this.props.testCallBack);
但是,如您所见,我正在修改生产中的组件仅用于测试目的,这非常丑陋。
现在,我的问题是:我该如何解决这个问题?
【问题讨论】:
-
您必须等待
fetch真正完成。请注意,fetch是异步的。见facebook.github.io/jest/docs/en/asynchronous.html -
这可能是因为当您执行
setState()时,组件重新渲染并且fetch在组件再次安装之前运行,在此期间您再次执行setState(),这可能导致这个问题。设置初始状态isLoading: true可以解决您的问题,因为您不必在获取之前setState()。 -
顺便说一句,您可能想在
componentWillReceiveProps中这样做 -
@Hamms 你的意思是旋转加载器还是什么?你能告诉我更多吗?
-
请看更新后的问题!
标签: reactjs unit-testing enzyme jestjs