调用分派后,React Context API不会更新

时间:2020-03-10 07:32:06

标签: javascript reactjs jestjs

我有一个登录组件,该组件在成功登录后以全局状态存储用户信息。登录组件非常简单。它包含一个带有handleSubmit事件的表单,该事件调用端点。根据该端点的结果,将采取措施。登录组件如下所示。

import React, { Component } from 'react';
import { StateContext } from '../state';
import { login } from '../repositories/authenticationRepository';

class Login extends Component {
    static contextType = StateContext;

    constructor(props) {
      super(props);
      this.state = {
        email: '',
        password: '',
        message: '',
      };
    }

    handleChange = (event) => {
      const { name, value } = event.target;
      this.setState({ [name]: value });
    }

    handleSubmit = async (event) => {
      event.preventDefault();
      const [{}, dispatch] = this.context;

      const { history } = this.props;
      const { email, password } = this.state;

      const isLoggedInResponse = await login({ email, password });
      if (isLoggedInResponse.data.type === 'error') {
        this.setState({ message: isLoggedInResponse.data.message });
        return;
      }

      dispatch({ type: 'storeUserInformation', userInformation: isLoggedInResponse.data.message });

      history.push('/');
    }

    render() {
      const { email, password, message } = this.state;
      return (
        <div className="login-wrapper">
          <form onSubmit={this.handleSubmit}>
            <label htmlFor="email">
              Email:
              <input autoComplete="off" name="email" type="text" value={email} onChange={this.handleChange} />
            </label>

            <label htmlFor="password">
              Password:
              <input autoComplete="off" id="password" name="password" type="password" value={password} onChange={this.handleChange} />
            </label>

            {message.length > 0 && <span className="text-danger error">{message}</span> }

            <input className="btn btn-secondary" type="submit" value="Submit" />
          </form>
        </div>
      );
    }
}

export default Login;

我自己进行测试时,可以看到在ReactJS devtools中设置的用户信息。当然,我想使用单元测试来自动测试它,所以我写了以下内容。

jest.mock('../../repositories/authenticationRepository');

import React from 'react';
import { mount } from 'enzyme';
import Login from '../../pages/Login';
import { StateProvider } from '../../state';
import { login } from '../../repositories/authenticationRepository';
import { act } from 'react-dom/test-utils';
import history from '../../sitehistory';
import { BrowserRouter as Router } from 'react-router-dom';
import { reducer } from '../../reducer';

it('Saves the user information in the store on a succesfull login', async () => {    
    login.mockReturnValue(({ data: { type: 'success', message: 'Message should be stored' }}));

    let initialStateMock = {}

    const wrapper = mount(
        <StateProvider initialState={initialStateMock} reducer={reducer}>
            <Router>
                <Login history={history} />
            </Router>   
        </StateProvider>
    );

    let emailEvent = { target: { name: 'email', value: 'test@example.com'} }
    let passwordEvent = { target: { name: 'password', value: 'password'} }

    wrapper.find('input').first().simulate('change', emailEvent);
    wrapper.find('input').at(1).simulate('change', passwordEvent);

    const submitEvent = { preventDefault: jest.fn() }

    await act(async () => {
        wrapper.find('form').first().simulate('submit', submitEvent);
    });

    act(() => {
        wrapper.update();
    });

    console.log(initialStateMock); // expected { userInformation: 'Message should be stored' } but got {}
});

我希望initialStatemock的值为{ userInformation: 'Message should be stored' }。但是,它的初始值仍为{}。我尝试wrapper.update()进行刷新,但无济于事。我忽略了什么?

0 个答案:

没有答案