Как заглушить асинхронное действие в componentDidMount для тестирования компонента с подключением к реактиву с помощью Jest - PullRequest
0 голосов
/ 15 мая 2019

У меня есть простой подключенный компонент, который при загрузке создает пользовательские данные, вызывая асинхронное действие, а затем отображает эти данные из состояния.

import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import { loadUserDetails } from '../actions/user';

class ShowUserDetailsLite extends React.Component {
  componentDidMount() {
    this.props.loadUserDetails();
  }

  render() {
    const { userDetails } = this.props;

    const handleClickEdit = () => {
      history.push(editProfilePath());
    };

    return (
      <div>
        <div className="email">
          {userDetails.email_address}
        </div>
        <div className="name">
          {userDetails.first_name} {userDetails.last_name}
        </div>
      </div>
    );
  }
}

ShowUserDetailsLite.propTypes = {
  loadUserDetails: PropTypes.func.isRequired,
  userDetails: PropTypes.shape({}).isRequired,
};

const mapDispatchToProps = {
  loadUserDetails,
};

function mapStateToProps(state) {
  const userDetails = state.user.details;
  return { userDetails };
}

export default connect(mapStateToProps, mapDispatchToProps)(ShowUserDetailsLite);

Для начала я хотел бы проверить, что мой компонент отображает правильную информацию из состояния, поэтому у меня есть следующий тест.

import configureStore from 'redux-mock-store'
import { shallow } from 'enzyme';
import { expect } from 'chai';
import React from 'react'
import Provider from 'react-redux';
import ShowUserDetailsLite from '../../components/ShowUserDetailsLite'

describe('ShowUserDetailsLite component', () => {
  it('displays the current user', () => {
    const mockStore = configureStore();
    let store = mockStore({
      user: {
        details: {
          email_address: 'test@test.com',
          first_name: 'First',
          last_name: 'Last',
        }
      },
    });
    let wrapper = shallow(<ShowUserDetailsLite store={store} loadUserDetails={jest.fn()}/>).dive()
    expect(wrapper.find('.email').text()).to.eql('test@test.com')
  })
})

Когда я запускаю этот тест с закомментированной функцией componentDidMount, он прекрасно работает, читается состояние и отображается правильная информация, но когда я запускаю тест, включающий функцию componentDidMount, тест пытается вызвать функцию и я получаю следующую ошибку:

 FAIL  app/tests/components/ShowUserDetailsLite.test.js
  ShowUserDetailsLite component
    ✕ displays the current user (32ms)

  ● ShowUserDetailsLite component › displays the current user

    ReferenceError: regeneratorRuntime is not defined

      16 |
      17 | export function loadUserDetails() {
    > 18 |   return async dispatch => {
         |   ^
      19 |     try {
      20 |       const res = await axios.get(`/${window.realm}/api/userDetails`);
      21 |       dispatch({ type: SET_USER_DETAILS, data: res.data });

На данном этапе меня не интересует тестирование функции loadUserDetails, поэтому я просто хочу ее заглушить. Я понял, что для этого вам просто нужно передать функцию как свойство, что я пытался сделать, передав функцию jest:

let wrapper = shallow(<ShowUserDetailsLite store={store} loadUserDetails={jest.fn()}/>).dive()

Но все же я получаю ошибку. Как правильно заблокировать асинхронные действия, вызываемые в componentdidmount для тестов подключенных компонентов?

...