Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.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
Javascript 反应+;Jest-测试异步组件并等待装载_Javascript_Reactjs_Jestjs_Enzyme - Fatal编程技术网

Javascript 反应+;Jest-测试异步组件并等待装载

Javascript 反应+;Jest-测试异步组件并等待装载,javascript,reactjs,jestjs,enzyme,Javascript,Reactjs,Jestjs,Enzyme,我正在测试一个React组件,它有一个异步componentDidMount 承诺本身不需要被嘲笑,它不一定是用来访问外部内容的,主要是用来包装道具的 然而,为了测试它,我需要使用wrapper.update()四次,这对我来说真的很奇怪 解决方案包括: 这一切对我都不起作用 下面是我的测试的样子(目前可以正常工作,但这个解决方案一点也不优雅,也不可扩展): 这种奇怪的行为可能是因为您对组件didmount实现使用了async 目前,所有React渲染过程都是同步的,因此与其渲染流相

我正在测试一个React组件,它有一个异步
componentDidMount

承诺本身不需要被嘲笑,它不一定是用来访问外部内容的,主要是用来包装道具的

然而,为了测试它,我需要使用
wrapper.update()
四次,这对我来说真的很奇怪

解决方案包括:

这一切对我都不起作用

下面是我的测试的样子(目前可以正常工作,但这个解决方案一点也不优雅,也不可扩展):


这种奇怪的行为可能是因为您对
组件didmount
实现使用了
async

目前,所有React渲染过程都是同步的,因此与其渲染流相关的所有内容都需要被视为同步的。目前,React团队正在开发一个突破性的变更特性,以允许

但是!即使在这个特性可用之后,请记住,
componentDidMount
仍然是同步的,所有其他钩子也是同步的,因此重要的是要知道React不会等待钩子内部的任何承诺


如果符合您的用例,您可以在
组件didmount
中启动承诺,并让解析结果更改状态。但是生命周期钩子将在解析之前完成,这将影响您的测试用例,因为测试需要等待解析承诺的结果得到处理,然后才能断言它,您可以使用它来保证这种行为。

我面临着完全相同的问题。 问题是测试不会等待承诺兑现。我的解决方案是使用Jest提供的done回调来表示测试结束

像这样:

it('wait async code before assert something', (doneCallback) => {
    const wrapper = shallow(<Component />);

    setImmediate(() => {
        expect(wrapper.find('.async').length).toBe(1);
        doneCallback();
    });
});
it('assert something'之前等待异步代码),(doneCallback)=>{
常量包装器=浅();
setImmediate(()=>{
expect(wrapper.find('.async').length.toBe(1);
doneCallback();
});
});
在这类问题上帮了我很大的忙。
通过添加
加载
状态,然后执行以下操作,您可以轻松地使其工作:

import * as React from 'react';
import { shallow, mount } from 'enzyme';
import LargeSelector from './LargeSelector';
import { waitForState } from 'enzyme-async-helpers';

describe('<LargeSelector />', async () => {

  describe('search', async () => {
    it('should save initial response in cache', async () => {
      const wrapper = await shallow(<LargeSelector query={async (search) => ['search:' + search]} />);

      await waitForState(wrapper, state => state.loading === false);

      expect(LargeSelector.prototype.componentDidMount).toHaveBeenCalledTimes(1); 
      expect(wrapper.state()).toHaveProperty('options', ['search:']);
      expect(wrapper.state()).toHaveProperty('initialOptions', ['search:']);
    });
  });
});
import*as React from'React';
从“酶”导入{shall,mount};
从“./LargeSelector”导入LargeSelector;
从“酶异步助手”导入{waitForState};
描述(“”,异步()=>{
描述('search',async()=>{
它('应该在缓存中保存初始响应',异步()=>{
const wrapper=await shall(['search:'+search]}/>);
等待waitForState(包装器,状态=>state.loading===false);
期望(大量的选择。原型。组件安装)。已收集时间(1);
expect(wrapper.state()).toHaveProperty('options',['search:']);
expect(wrapper.state()).toHaveProperty('initialOptions',['search:']);
});
});
});
和:
this.setState({initialOptions:results})

必须更新为:

this.setState({initialOptions:results,loading:false})

如果componentDidMount中存在任何异步调用,则此问题仍然存在。有没有办法专门挂接到componentDidMount并等待它?(js.runAllTicks()没有帮助)让我们看看,在测试中,您可以删除
async
,特别是
wait
for
shallow
update
,您不需要它,因为一切都是同步的。除此之外,测试不需要监视
组件didmount
,因为它是隐式测试的,如果状态因为其中的代码而改变,这意味着它被正确调用,这只是一个小小的改进。尝试记录异步函数完成的步骤,以便我们讨论。如果
runAllTicks()
不起作用,请尝试此常用解决方案:而runall Ticks对我不起作用。这个解释真的帮助我理解了代码流程,谢谢。这非常有效,谢谢!
it('wait async code before assert something', (doneCallback) => {
    const wrapper = shallow(<Component />);

    setImmediate(() => {
        expect(wrapper.find('.async').length).toBe(1);
        doneCallback();
    });
});
import * as React from 'react';
import { shallow, mount } from 'enzyme';
import LargeSelector from './LargeSelector';
import { waitForState } from 'enzyme-async-helpers';

describe('<LargeSelector />', async () => {

  describe('search', async () => {
    it('should save initial response in cache', async () => {
      const wrapper = await shallow(<LargeSelector query={async (search) => ['search:' + search]} />);

      await waitForState(wrapper, state => state.loading === false);

      expect(LargeSelector.prototype.componentDidMount).toHaveBeenCalledTimes(1); 
      expect(wrapper.state()).toHaveProperty('options', ['search:']);
      expect(wrapper.state()).toHaveProperty('initialOptions', ['search:']);
    });
  });
});