vendredi 26 mai 2017

Testing React component with dynamic import (Enzyme/Mocha)

I'm trying to test a React component using Mocha and Enzyme that uses a dynamic import to load a module.

When I try to test the logic that relies on the dynamic import I get incorrect results. The problem is that the async functions don't finish before the test finishes so I can never get accurate results.

How can I handle this scenario?

Component

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;

Test

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
  });
});

Aucun commentaire:

Enregistrer un commentaire