在componentDidMount中获取数据后,如何测试React组件? [英] how to test a react component after data is fetch in componentDidMount?

查看:98
本文介绍了在componentDidMount中获取数据后,如何测试React组件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有条件的反应组件(有条件渲染)(如果获取数据则渲染,否则返回null),我想用jest & enzyme对此进行测试.我遇到的问题是我想测试该类中的一种方法,但是.instance()始终返回null,因此不允许我测试该实例.

I have a react component that renders conditionally (renders if data is fetched otherwise returns null) and I want to test this with jest & enzyme. The problem that I'm having is I want to test one of the methods in the class but .instance() keeps returning null so it doesn't allow me to test the instance.

我的代码看起来像这样

export default class MyComponent extends React.Component<Props, State> {
    componentDidMount() {
        this.props.fetchData.then(() => 
            this.setState({ loaded: true });
        );
    }

    methodThatIWantToTest() {
        //do some stuff here
    }

    render() {
        if (this.loaded) {
            // render stuff here
        } else {
            return null;
        }
    }
}

在测试中我想测试

describe('myComponent', () => {
   it('should do some stuff', () => {
      const shallowWrapper = shallow(<MyComponent {...props}/>);
      const method = shallowWrapper.instance().methodThatIWantToTest();
      ....such and such

   });
});

,但看起来MyComponent仅返回null,因此shallowWrapper.instance()也返回null.我尝试了shallowWrapper.update()和许多其他操作,但似乎根本不想渲染..如何等待组件更新然后启动expect语句?

but it looks like MyComponent only returns null so shallowWrapper.instance() returns null as well. I tried shallowWrapper.update() and many other things but it seems it doesn't want to render at all.. How do I wait for my component to be updated and then starts expect statement?

有人遇到过与我类似的问题,并且知道如何解决此问题吗?

has anyone had a similar issue as mine and know how to work around this?

推荐答案

它是render结果,而不是null实例. shallowWrapper.instance()是组件类的实例,对于有状态组件,不能为null.正如参考所述:

It is render result and not an instance that is null. shallowWrapper.instance() is an instance of component class, it cannot be null for stateful component. As the reference states:

返回(反应16.x)

Returns (React 16.x)

ReactComponent:有状态的React组件实例.

ReactComponent: The stateful React component instance.

null:如果包装了无状态React组件.

null: If stateless React component was wrapped.

shallowWrapper.html()最初确实是null.

原始代码中有一个错误,应该是this.state.loaded而不是this.loaded:

There is a mistake in original code, it should be this.state.loaded and not this.loaded:

MyComponent extends React.Component {
  state = { loaded: false };

  componentDidMount() {
    this.props.fetchData.then(() => {
          this.setState({ loaded: true });
    });
  }

  methodThatIWantToTest() {
      //do some stuff here
  }

  render() {
      if (this.state.loaded) {
          return <p>hi</p>;
      } else {
          return null;
      }
  }
}

最好将

componentDidMountmethodThatIWantToTest视为不同的单元.它们属于不同的测试.如果methodThatIWantToTest在生命周期挂钩中被调用,则可能会在componentDidMount测试中将其存根:

componentDidMount and methodThatIWantToTest should be preferably considered different units. They belong to different tests. In case methodThatIWantToTest is called in lifecycle hooks, it may be stubbed in componentDidMount test:

   it('should fetch data', async () => {
      const props = { fetchData: Promise.resolve('data') };
      const shallowWrapper = shallow(<MyComponent {...props}/>);
      expect(shallowWrapper.html()).toBe(null);
      await props.fetchData;
      expect(shallowWrapper.html()).toBe('<p>hi</p>');
   });

然后可以单独测试该方法.可以禁用生命周期挂钩,以减少活动部件的数量:

Then the method can be tested separately. Lifecycle hooks can be disabled to reduce number of moving parts:

   it('should do some stuff', () => {
      const shallowWrapper = shallow(<MyComponent {...props}/>, {disableLifecycleMethods: true});
      const result = shallowWrapper.instance().methodThatIWantToTest();
      expect(result).toBe(...);    
   });

这篇关于在componentDidMount中获取数据后,如何测试React组件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆