Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.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 Jest使用setTimeout测试钩子状态更新_Reactjs_Jestjs_Settimeout_Enzyme - Fatal编程技术网

Reactjs Jest使用setTimeout测试钩子状态更新

Reactjs Jest使用setTimeout测试钩子状态更新,reactjs,jestjs,settimeout,enzyme,Reactjs,Jestjs,Settimeout,Enzyme,我试图用一个点击处理程序测试卸载一个自毁组件。单击处理程序使用setTimeout更新useState 然而,我的测试失败了,而我希望它能通过。我尝试使用诸如advanceTimersByTime()之类的玩笑模拟计时器,但它不起作用。如果我在setTimeout之外调用setState,则测试通过 component.js const-DangerMsg=({duration,onAnimDurationEnd,children})=>{ const[isVisible,setVisible]

我试图用一个点击处理程序测试卸载一个自毁组件。单击处理程序使用setTimeout更新useState

然而,我的测试失败了,而我希望它能通过。我尝试使用诸如advanceTimersByTime()之类的玩笑模拟计时器,但它不起作用。如果我在setTimeout之外调用setState,则测试通过

component.js

const-DangerMsg=({duration,onAnimDurationEnd,children})=>{
const[isVisible,setVisible]=useState(false);
const[sectionClass,setSectionClass]=useState(classes.container);
函数handleAnimation(){
setSectionClass(classes.containerAnimated);
let timer=setTimeout(()=>{
setVisible(假);
}, 300);
返回clearTimeout(计时器);
}
useffect(()=>{
让计时器1;
让时间2;
函数animate(){
如果(onAnimDurationEnd){
setSectionClass(classes.containerAnimated);
timer2=设置超时(()=>{
setVisible(假);
}, 300);
}否则{
setVisible(假);
}
}
if(儿童){
setVisible(真);
}
如果(持续时间){
timer1=设置超时(()=>{
制作动画();
},持续时间);
}
return()=>{
清除超时(计时器1);
清除超时(timer2);
};
},[children,duration,onAnimDurationEnd]);
返回(
{是可见的吗(
{儿童}
handleAnimation()}
数据测试=“btn”
>
&时代;
):null}
);
})

出口违约风险

test.js

it(“单击时不应渲染”,async()=>{
开玩笑。使用faketimers();
const{useState}=jest.requireActual(“react”);
useStateMock.mockImplementation(useState);
//在浅层上未调用useEffect
组件=安装(
);
常量btn=findByTestAttr(组件,“btn”);
模拟(“点击”);
玩笑时间(400);
const wrapper=findByTestAttr(组件,“危险消息”);
expect(wrapper).toHaveLength(0);
});

注意,我正在用actual模拟useState实现,因为在其他测试中我使用了自定义useState模拟。

没有使用酶,而是使用
测试库/react
,因此这是一个部分解决方案。以下测试按预期通过:

  test("display loader after 1 second", () => {
    jest.useFakeTimers(); // mock timers
    const { queryByRole } = render(
      <AssetsMap {...defaultProps} isLoading={true} />
    );
    act(() => {
      jest.runAllTimers(); // trigger setTimeout
    });
    const loader = queryByRole("progressbar");
    expect(loader).toBeTruthy();
  });
test(“1秒后显示加载程序”,()=>{
jest.useFakeTimers();//模拟计时器
常量{queryByRole}=render(
);
行动(()=>{
jest.runAllTimers();//触发器设置超时
});
常量加载器=queryByRole(“progressbar”);
expect(loader.toBeTruthy();
});

我直接运行计时器,但按时间推进应该会得到类似的结果。

Hi,完全相同的问题,使用
测试libarry
而不是酶。更广泛地说,问题是在状态更改后模拟组件的重新加载。对我来说,
rerender
似乎不起作用。仅供参考:
useFakeTimers
有一个可选参数
implementation
,用于在传统实现(jest自己的)和现代实现(sinon的伪计时器)之间进行选择。对于lodash debounce使用的假计时器,请使用
modern
。可以找到更多信息。还有这个。
it("should NOT render on click", async () => {
    jest.useFakeTimers();
    const { useState } = jest.requireActual("react");
    useStateMock.mockImplementation(useState);
    // useEffect not called on shallow
    component = mount(
        <DangerMsg>
            <div></div>
        </DangerMsg>
    );
    const btn = findByTestAttr(component, "btn");
    btn.simulate("click");
    jest.advanceTimersByTime(400);
    const wrapper = findByTestAttr(component, "danger-msg");
    expect(wrapper).toHaveLength(0);
});
  test("display loader after 1 second", () => {
    jest.useFakeTimers(); // mock timers
    const { queryByRole } = render(
      <AssetsMap {...defaultProps} isLoading={true} />
    );
    act(() => {
      jest.runAllTimers(); // trigger setTimeout
    });
    const loader = queryByRole("progressbar");
    expect(loader).toBeTruthy();
  });