reactjs - 使用动态导入测试 React 组件 (Enzyme/Mocha)

标签 reactjs testing async-await mocha.js enzyme

我正在尝试使用 Mocha 和 Enzyme 测试 React 组件,该组件使用动态导入来加载模块。

当我尝试测试依赖于动态导入的逻辑时,我得到了不正确的结果。问题是异步函数不会在测试完成之前完成,所以我永远无法获得准确的结果。

我该如何处理这种情况?

组件

import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';

// styles

import styles from './PasswordStrengthIndicator.scss';

class PasswordStrengthIndicator extends React.Component {
  static defaultProps = {
    password: undefined,
    onPasswordChange: undefined,
  }

  static propTypes = {
    password: PropTypes.string,
    onPasswordChange: PropTypes.func,
  }

  constructor() {
    super();

    this.state = {};
  }

  componentWillMount() {
    this.handlePasswordChange();
  }

  componentWillReceiveProps(nextProps) {
    const password     = this.props.password;
    const nextPassword = nextProps.password;

    if (password !== nextPassword) {
      this.handlePasswordChange();
    }
  }

  render() {
    const strength = this.state.strength || {};
    const score    = strength.score;

    return (
      <div className={ styles.passwordStrength }>
        <div className={ classNames(styles.score, styles[`score-${score}`]) } />
        <div className={ styles.separator25 } />
        <div className={ styles.separator50 } />
        <div className={ styles.separator75 } />
      </div>
    );
  }

  // private

  async determineStrength() {
    const { password } = this.props;
    const zxcvbn = await import('zxcvbn');

    let strength = {};

    if (password) strength = zxcvbn(password);

    return strength;
  }

  async handlePasswordChange() {
    const { onPasswordChange } = this.props;
    const strength = await this.determineStrength();

    this.setState({ strength });

    if (onPasswordChange) onPasswordChange(strength);
  }
}

export default PasswordStrengthIndicator;

测试

describe('when `password` is bad', () => {
  beforeEach(() => {
    props.password = 'badpassword';
  });

  it.only('should display a score of 1', () => {
    const score = indicator().find(`.${styles.score}`);

    expect(score.props().className).to.include(styles.score1); // should pass
  });
});

最佳答案

我能够通过 -- 某事 实现这一目标。

我将依赖动态导入的测试切换为异步测试。然后我创建了一个函数来呈现组件并返回一个 promise ,该 promise 动态地导入我试图在组件中导入的模块。

const render = () => {
  indicator = shallow(
    <PasswordStrengthIndicator { ...props } />,
  );

  return (
    Promise.resolve()
      .then(() => import('zxcvbn'))
  );
};

我相信这依赖于与等待相同的概念,因为 import('zxcvbn') 将花费足够多的时间在两个地方导入。

这是我的测试代码:

describe('when `password` is defined', () => {
  describe('and password is bad', () => {
    beforeEach(() => {
      props.password = 'badpassword';
    });

    it('should display a score of 1', (done) => {
      render()
        .then(() => {
          const score = indicator.find(`.${styles.score}`);

          expect(score.props().className).to.include(styles.score1);

          done();
        });
    });
  });
});

这最终成功了,因为它使我不必 stub ,而且我不必更改组件的实现以更好地支持 stub 。它也没有等待 x 毫秒那么随意。

我暂时保留这个问题,因为社区可能会提供更好的解决方案。

关于reactjs - 使用动态导入测试 React 组件 (Enzyme/Mocha),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44208207/

相关文章:

c# - 没有异步 API 时如何并行化 I/O 操作

javascript - 如何处理 react/redux 中的副作用?

reactjs - 如何在 React 应用程序中模拟 linux 终端

javascript - 如何将 HTML 小部件代码转换为 NEXTjs 代码以在应用程序中使用(CoinMarketCap 价格选取框)

angular - 如何不忘记再次打开 Protractor 到 Angular 同步?

javascript - 异步函数中的同步异常

javascript - 如何在 react-admin 中访问自定义组件中的表单数据?

未定义 Python 全局变量 - 在类内部声明

node.js - Mocha + Chai - 没有关于错误的详细信息

c# - Fluent-ASsertions ShouldRaisePropertyChangeFor 不适用于异步任务?