21
  • React v15.1.0
  • ジェスト v12.1.1
  • 酵素 v2.3.0

クリックによって呼び出される関数でプロミスを呼び出すコンポーネントをテストする方法を見つけようとしています。ここで Jest のrunAllTicks()機能が役立つことを期待していましたが、約束を実行していないようです。

成分:

import React from 'react';
import Promise from 'bluebird';

function doSomethingWithAPromise() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, 50);
  });
}

export default class AsyncTest extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      promiseText: '',
      timeoutText: ''
    };

    this.setTextWithPromise = this.setTextWithPromise.bind(this);
    this.setTextWithTimeout = this.setTextWithTimeout.bind(this);
  }

  setTextWithPromise() {
    return doSomethingWithAPromise()
      .then(() => {
        this.setState({ promiseText: 'there is text!' });
      });
  }

  setTextWithTimeout() {
    setTimeout(() => {
      this.setState({ timeoutText: 'there is text!' });
    }, 50);
  }

  render() {
    return (
      <div>
        <div id="promiseText">{this.state.promiseText}</div>
        <button id="promiseBtn" onClick={this.setTextWithPromise}>Promise</button>
        <div id="timeoutText">{this.state.timeoutText}</div>
        <button id="timeoutBtn" onClick={this.setTextWithTimeout}>Timeout</button>
      </div>
    );
  }
}

そしてテスト:

import AsyncTest from '../async';
import { shallow } from 'enzyme';
import React from 'react';

jest.unmock('../async');

describe('async-test.js', () => {
  let wrapper;

  beforeEach(() => {
    wrapper = shallow(<AsyncTest />);
  });

  // FAIL
  it('displays the promise text after click of the button', () => {
    wrapper.find('#promiseBtn').simulate('click');

    jest.runAllTicks();
    jest.runAllTimers();

    wrapper.update();

    expect(wrapper.find('#promiseText').text()).toEqual('there is text!');
  });

  // PASS
  it('displays the timeout text after click of the button', () => {
    wrapper.find('#timeoutBtn').simulate('click');

    jest.runAllTimers();

    wrapper.update();

    expect(wrapper.find('#timeoutText').text()).toEqual('there is text!');
  });
});
4

2 に答える 2

1

テストを終了する前に、約束が果たされるのを何らかの形で待つ必要はほとんどありません。私が見ることができるコードからそれを行うには、主に2つの方法があります。

  1. onClickそれとあなたの約束の方法を個別にテストしてください。したがって、正しい関数を呼び出すことを確認しonClickますが、 をスパイしsetTextWithPromise、クリックをトリガーし、呼び出されたことをアサートしますsetTextWithPromise。次に、コンポーネント インスタンスを取得し、ハンドラーをアタッチして正しいことをアサートできるという約束を返すそのメソッドを呼び出すこともできます。

  2. promise が解決されたときに呼び出される、渡すことができるコールバック prop を公開します。

于 2016-05-24T12:11:21.760 に答える