如何在调用更新状态的组件方法之后测试React状态

编程入门 行业动态 更新时间:2024-10-27 07:28:50
如何在调用更新状态的组件方法之后测试React状态 - 使用Enzyme(How to test React state after calling a component method that updates state - using Enzyme)

酶新手在这里。 我试图在调用该组件上的方法后测试是否正在更新React组件的状态。

这是我正在测试的组件的片段:

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  state = {
    recipes: {},
    user: null
  };

  handleUnauth = () => {
    this.setState({
      user: null
    });
  };

  render() {
   //render children, pass down methods as props etc...
  }

}
 

以下是测试:

import createRouterContext from 'react-router-test-context';
import { shallow, mount } from 'enzyme';
import expect from 'expect';
import React from 'react';

import App from 'App';  //import with webpack alias

describe('App', () => {

  let wrapper, context;

  beforeEach(() => {
    context = createRouterContext();
    wrapper = mount(<App/>, { context });
  });

  it('should remove logged in user details on logout', () => {
    const user = {
      uid: 'abc123',
      name: 'John Doe'
    };

    wrapper.setState({ user }, () => {
      wrapper.instance().handleUnauth();
      const userState = wrapper.state('user');
      expect(userState).toEqual(null);
    });

  });

});
 

我的测试失败,出现以下错误:

我知道更新状态不是同步的,但我不确定这是否与此有关,或者是否有更好的方法使用Enzyme进行测试。 如果有人能指出我正确的方向,我将非常感激。 哦,我通过在测试中调用wrapper.instance().handleUnauth()之后调用wrapper.instance().handleUnauth()尝试这个,但是这也没有用。

Enzyme newbie here. I am trying to test if the state of a React component is being updated after calling a method on that component.

This is a snippet of the component that I am testing:

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  state = {
    recipes: {},
    user: null
  };

  handleUnauth = () => {
    this.setState({
      user: null
    });
  };

  render() {
   //render children, pass down methods as props etc...
  }

}
 

Below is the test:

import createRouterContext from 'react-router-test-context';
import { shallow, mount } from 'enzyme';
import expect from 'expect';
import React from 'react';

import App from 'App';  //import with webpack alias

describe('App', () => {

  let wrapper, context;

  beforeEach(() => {
    context = createRouterContext();
    wrapper = mount(<App/>, { context });
  });

  it('should remove logged in user details on logout', () => {
    const user = {
      uid: 'abc123',
      name: 'John Doe'
    };

    wrapper.setState({ user }, () => {
      wrapper.instance().handleUnauth();
      const userState = wrapper.state('user');
      expect(userState).toEqual(null);
    });

  });

});
 

My test fails with the following error:

I understand that updating of state is not synchronous but I am not sure if that has something to do with this or if there are better ways to test this using Enzyme. Would be super grateful if someone can please point me in the right direction. Oh and I tried this by calling wrapper.update() right after calling wrapper.instance().handleUnauth() in the test but this too didn't work.

最满意答案

从React#setState ,

setState(updater,[callback])

setState()将组件状态的更改排入队列。 setState不会立即更新状态。 setState()并不总是立即更新组件。 它可以批量推迟更新或推迟更新。 这使得在调用setState()之后立即读取this.state是一个潜在的陷阱。相反,使用componentDidUpdate或setState回调(setState(updater, callback))

解决方案1:

从setState删除回调;

wrapper.setState({ user }); wrapper.instance().handleUnauth(); const userState = wrapper.state('user'); expect(userState).toEqual(null);

解决方案2:

读取setState callback的callback参数中的更新状态

wrapper.setState({ user }, (userState) => { wrapper.instance().handleUnauth(); //const userState = wrapper.state('user'); // comment it. expect(userState).toEqual(null); });

From the React#setState,

setState(updater, [callback])

setState() enqueues changes to the component state. The setState doesn't immediately update the state. setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall.Instead, use componentDidUpdate or a setState callback (setState(updater, callback))

Solution 1:

Remove callback from setState;

wrapper.setState({ user }); wrapper.instance().handleUnauth(); const userState = wrapper.state('user'); expect(userState).toEqual(null);

Solution 2:

Read the updated state in the callback parameter of setState callback

wrapper.setState({ user }, (userState) => { wrapper.instance().handleUnauth(); //const userState = wrapper.state('user'); // comment it. expect(userState).toEqual(null); });

更多推荐

本文发布于:2023-08-03 08:53:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1385225.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:状态   组件   测试   方法   如何在

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!