Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.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 用酶测试时,如何等待组件安装中的设置状态解决?_Reactjs_Jestjs_Enzyme - Fatal编程技术网

Reactjs 用酶测试时,如何等待组件安装中的设置状态解决?

Reactjs 用酶测试时,如何等待组件安装中的设置状态解决?,reactjs,jestjs,enzyme,Reactjs,Jestjs,Enzyme,我试图测试一个React组件,它运行一些异步代码并在componentDidMount中调用setState 下面是我要测试的react组件: /** * * AsyncComponent * */ import React from 'react'; class AsyncComponent extends React.Component { constructor(props) { super(props); this.state = { loaded:

我试图测试一个React组件,它运行一些异步代码并在componentDidMount中调用setState

下面是我要测试的react组件:

/**
*
* AsyncComponent
*
*/

import React from 'react';

class AsyncComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loaded: false,
      component: null,
    };
  }
  componentDidMount() {
    this.props.component.then(component => {
       this.setState({
         loaded: true,
         component: component.default ? component.default : component,
       });
    });
  }
  render() {
    if (!this.state.loaded) {
      return null;
    }

    const Component = this.state.component;

    const { component, ...rest } = this.props;

    return <Component {...rest} />;
  }
}

export default AsyncComponent;
/**
*
*异步组件
*
*/
从“React”导入React;
类AsyncComponent扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
加载:false,
组件:null,
};
}
componentDidMount(){
this.props.component.then(component=>{
这是我的国家({
是的,
component:component.default?component.default:component,
});
});
}
render(){
如果(!this.state.loaded){
返回null;
}
const Component=this.state.Component;
const{component,…rest}=this.props;
返回;
}
}
导出默认异步组件;
下面是测试用例。我在用玩笑和酶

import React from 'react';
import { mount } from 'enzyme';

import AsyncComponent from '../index';

const TestComponent = () => <div>Hello</div>;

describe('<AsyncComponent />', () => {
  it('Should render loaded component.', () => {
    const promise = Promise.resolve(TestComponent);
    const rendered = mount(<AsyncComponent component={promise} />);
    expect(rendered.state().loaded).toBe(true);
  });
});
从“React”导入React;
从“酶”导入{mount};
从“../index”导入异步组件;
const TestComponent=()=>Hello;
描述(“”,()=>{
它('应该呈现加载的组件',()=>{
const promise=promise.resolve(TestComponent);
const rendered=mount();
expect(rendered.state().loaded).toBe(true);
});
});
测试失败,因为state.loaded仍设置为false。在调用expect之前,是否有办法确保AsyncComponent已完全加载


如果我将expect断言包装在setTimeout中,我可以让它工作,但这似乎是一种相当粗糙的方法。我应该怎么做呢?

您需要通过使用
async/await
或从测试中返回承诺来通知jest有关承诺,请查看

描述(“”,()=>{
它('应该呈现加载的组件',async()=>{
const promise=promise.resolve(TestComponent);
const rendered=mount();
等待承诺
expect(rendered.state().loaded).toBe(true);
});
});

我遇到了同样的问题,我想出了一些笨拙的解决方案,我在componentDidMount中调用了一些函数,我想检查该函数是否已被调用,这样代码就适合我了

const loadFiltersTree = jest.fn()   
const wrapper = shallow(<FilterTree loadFiltersTree={loadFiltersTree} />)
jest.useFakeTimers()
jest.runAllTimers()
setImmediate(() => {
  expect(loadFiltersTree.mock.calls.length).toEqual(1)
})
const loadFiltersTree=jest.fn()
常量包装器=浅()
开玩笑
jest.runAllTimers()
setImmediate(()=>{
expect(loadFiltersTree.mock.calls.length).toEqual(1)
})

破坏承诺链是常见的反模式。根据经验,使用承诺的函数应该将结果承诺返回给链,除非这会导致问题。这保证了调用方函数链接承诺时不会出现竞争条件。其中一个原因是提高了可测试性。这也适用于生命周期挂钩,如
componentDidMount

componentDidMount() {
  return this.props.component.then(...)
}
jest.spyOn(AsyncComponent.prototype, 'componentDidMount');
const wrapper = mount(<AsyncComponent component={promise} />);
expect(wrapper.instance().componentDidMount).toHaveBeenCalledTimes(1);
await wrapper.instance().componentDidMount.mock.results[0].value;
expect(wrapper.state().loaded).toBe(true);
异步Jest测试应该链接所有正在使用的承诺并返回一个承诺<代码>异步..等待是一种实用的方法

在Ezyme中,浅层渲染允许禁用自动
componentDidMount
调用并链接lifecycle hook返回的承诺:

const wrapper = shallowMount(<AsyncComponent component={promise} />,
  { disableLifecycleMethods: true });
await wrapper.instance().componentDidMount();
expect(wrapper.state().loaded).toBe(true);

我尝试使用您的代码,但测试失败,因为“rendered.state().loaded”仍然等于false。您可以检查承诺中的回调是否被调用吗?
promise.resolve(TestComponent)
立即与该组件解析。它与
setState
和准备测试的组件无关。这段代码毫无意义,肯定不能解决所描述的问题。这是不正确的
Promise.resolve()
不会立即计算,所有测试代码都将在调用
componentDidMount
调用中的回调之前运行。为了更好地理解承诺的执行顺序,请查看:。第一个例子正好说明了这种情况。当然,
async/await
看起来像是一个黑客,Jest团队正在考虑一个功能来解决所有的承诺,就像它对
setTimeout
所做的那样,但到目前为止,这个操作系统是一个可能的解决方案。另一种方法是返回已解析的承诺,并在
中进行
expect
调用,然后进行
回调
jest.spyOn(AsyncComponent.prototype, 'componentDidMount');
const wrapper = mount(<AsyncComponent component={promise} />);
expect(wrapper.instance().componentDidMount).toHaveBeenCalledTimes(1);
await wrapper.instance().componentDidMount.mock.results[0].value;
expect(wrapper.state().loaded).toBe(true);