Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 酶不';t在异步setState回调中反映setState更改_Reactjs_Unit Testing_Jestjs_Enzyme - Fatal编程技术网

Reactjs 酶不';t在异步setState回调中反映setState更改

Reactjs 酶不';t在异步setState回调中反映setState更改,reactjs,unit-testing,jestjs,enzyme,Reactjs,Unit Testing,Jestjs,Enzyme,我花了一整天的时间想弄明白这一点,但我无法让它发挥作用 我有一个组件更新componentDidMount中的状态,然后在setState的回调中,我再次更新状态,但回调异步运行。这是因为我在那里发出了一个http请求,我使用它的响应来更新状态。在单元测试期间,我模拟了这个模块,因此它不会到达网络。但Ezyme不能反映异步回调中的状态变化。这是有道理的,因为它是异步的,但我还没有找到任何解决方法 我已经建立了一个我试图实现的缩小版本 这是我的组件: 类组件扩展React.Component{ 建

我花了一整天的时间想弄明白这一点,但我无法让它发挥作用

我有一个组件更新
componentDidMount
中的状态,然后在
setState的
回调中,我再次更新状态,但回调异步运行。这是因为我在那里发出了一个http请求,我使用它的响应来更新状态。在单元测试期间,我模拟了这个模块,因此它不会到达网络。但Ezyme不能反映异步回调中的状态变化。这是有道理的,因为它是异步的,但我还没有找到任何解决方法

我已经建立了一个我试图实现的缩小版本

这是我的组件:

类组件扩展React.Component{
建造师(道具){
超级(道具);
此.state={
值:0,
};
这个。_isMounted=false;
}
componentDidMount(){
这个。_isMounted=true;
this.setState(state=>{
const{value}=this.state;
返回{
……国家,
值:值+15,
};
},异步()=>{
试一试{
//如果删除此行,它将正常工作。
等待承诺。决心(15);
如果(此项已安装){
this.setState(state=>{
const{value}=this.state;
//如果在测试期间使用console.log,
//此值已正确更新,但不能反映它。
返回{
……国家,
值:值+15,
};
});
}
}捕获(e){
//什么也不做。。。
}
});
}
组件将卸载(){
这个。_isMounted=false;
}
render(){
const{value}=this.state;
返回(
{value}
);
}
}
这是我的测试:

description('成分酶缺陷测试',()=>{
它('应该正确更新值',()=>{
const wrapper=shallow(,{disableLifecycleMethods:true});
wrapper.instance().componentDidMount();
expect(wrapper.state().value).toEqual(30);
});
});

在测试运行中,
state()。这意味着它注册了第一个更改,但没有注册第二个更改。

当在节点中执行IO绑定代码时,这些操作的回调不会在当前上下文中运行,它们会被放回事件循环()上,然后在下一个“勾号”上执行。这实际上意味着,当您运行调用异步代码的同步代码时,即使异步代码实际上不是异步的(例如,
Promise.resolve
),它仍将在同步代码运行完成后运行

在您的案例中,正如您在代码注释中所提到的,只有在您引入
Promise.resolve
时,测试才开始失败,这是因为此时我们将状态更改转移到不同的上下文,然后测试运行到完成,断言失败(希望您现在能够理解原因)

要修复测试,这相当简单,因为知道状态更新现在将在下一次运行,我们只想安排断言执行相同的操作:

it('should update value properly', done => {
  const wrapper = shallow(<Component />, { disableLifecycleMethods: true });
  wrapper.instance().componentDidMount();
  process.nextTick(() => {
    expect(wrapper.state().value).toEqual(30);
    done();
  })
});
it('应该正确更新值',完成=>{
const wrapper=shallow(,{disableLifecycleMethods:true});
wrapper.instance().componentDidMount();
process.nextTick(()=>{
expect(wrapper.state().value).toEqual(30);
完成();
})
});

这将断言放在与状态更新相同的刻度上运行,根据本文,我们知道事件循环阶段遵循FIFO模型,因此我们可以保证断言将在状态更新后运行。

当在节点中执行IO绑定代码时,这些操作的回调不会在当前上下文中运行,它们被放回事件循环()上,然后在下一个“勾选”时执行。这实际上意味着,当您运行调用异步代码的同步代码时,即使异步代码实际上不是异步的(例如,
Promise.resolve
),它仍将在同步代码运行完成后运行

在您的案例中,正如您在代码注释中所提到的,只有在您引入
Promise.resolve
时,测试才开始失败,这是因为此时我们将状态更改转移到不同的上下文,然后测试运行到完成,断言失败(希望您现在能够理解原因)

要修复测试,这相当简单,因为知道状态更新现在将在下一次运行,我们只想安排断言执行相同的操作:

it('should update value properly', done => {
  const wrapper = shallow(<Component />, { disableLifecycleMethods: true });
  wrapper.instance().componentDidMount();
  process.nextTick(() => {
    expect(wrapper.state().value).toEqual(30);
    done();
  })
});
it('应该正确更新值',完成=>{
const wrapper=shallow(,{disableLifecycleMethods:true});
wrapper.instance().componentDidMount();
process.nextTick(()=>{
expect(wrapper.state().value).toEqual(30);
完成();
})
});

这将断言放在与状态更新相同的刻度上运行,根据文章,我们知道事件循环阶段遵循FIFO模型,因此我们可以保证断言将在状态更新之后运行。

Woah,我不知道这些。非常感谢!:)哇,我一点都不知道。非常感谢!:)