web-dev-qa-db-ja.com

Jest反応テスト:遅延後の状態を確認

Jestのドキュメントの助けを借りてテストを作成しようとして本当に混乱しています https://facebook.github.io/jest/docs/timer-mocks.html#content

(setTimeout()を使用して)状態の値を手動で設定した後、コンテナーがマウントされたときの状態を確認し、数秒後に状態を確認しようとしています。

MainのcomponentDidMount内に次のような関数があります。

componentDidMount() {
    this.setStateAfterDelay();
}

そして、関数は何をします:

setStateAfterDelay = () => {
    setTimeout(() => {
        this.setState({ fruits: ['banana', 'Apple', 'orange', 'vodka', 'kiwi'] });
    }, 1500);
}

私は最初の部分を達成しました:

const component = mount(<Main />);
expect(component.state().fruits).toEqual(null);

しかし、後で状態をもう一度確認する方法がわかりません。2000msとしましょう。

どんな助けでもありがたいです:)

13
Jack M.

このコードは実際にはテストしていません。しかし、これに似たものがうまくいくと思います。

const fruits = ['banana', 'Apple', 'orange', 'vodka', 'kiwi'];

it('mock setTimeout test', () => {
 jest.useFakeTimers();
 setTimeout(() => {
   expect(component.state().fruits).toEqual(fruits);
 }, 1500);
 jest.runAllTimers();
});
15
Dinesh Ramasamy

jestは非同期コードを簡単に実行できますが、promiseとsetTimeoutの組み合わせを使用して少し待つことができます。たとえば、次のコードは2秒間待機します。

_await new Promise((r) => setTimeout(r, 2000));
_

完全なサンプルテスト。コールバック関数の前にasyncフラグを追加することを忘れないでください:

_test('some test title', async () => {
  const foo = true;
  await new Promise((r) => setTimeout(r, 2000));
  expect(foo).toBeDefined();
});
_

また、デフォルトの「タイムアウト」は5秒(5000ms)であることに注意してください。テストの実行時間が長くなる可能性がある場合は、jest.setTimeout(30000);の上にtest()を追加できます。 30000は、30秒間タイムアウトしないことを確認します。必要な数を追加できます。 setTimeoutの完全な例:

_jest.setTimeout(30000);

test('some test title', async () => {
  const foo = true;
  await new Promise((r) => setTimeout(r, 2000));
  expect(foo).toBeDefined();
});
_
6
Lukas

テストを遅らせる必要はありません。アサートする前にjest.runAllTimers()を呼び出すだけで機能します。

_const fruits = ['banana', 'Apple', 'orange', 'vodka', 'kiwi'];

it('initializes the fruits state', () => {
 jest.useFakeTimers();
 jest.runAllTimers();
 expect(component.state().fruits).toEqual(fruits);
});
_

複数回テストする場合は、beforeEachuseFakeTimers()を呼び出すこともできます。また、runAllTimers()を別のbeforeEach内に置くこともできるため、 t繰り返します。

2
Warao

これは、20秒後に何かを確認する方法に関する質問であることを知っています。しかし、これは、20秒をテストしたくないというインジケーターになる場合もあります。重要なのは、特定のアクションが正しい入力で実行されたかどうかということです。この場合、ディスパッチ関数を渡すことができるようにコードを少し再構成できます。例えば

    function abc() {
        return dispatch => {
            return Promise.then(res => {})  // this would take 20 seconds
        }
    }

dispatchが渡されるため、テストコードで以下を簡単に使用できます。

    const dispatch = Jest.fn()
    abc(dispatch)
    expect(dispatch).toBeCalled()

もちろん、20秒かどうかは気にせず、代わりにワークフロープロセスに気を配ることを前提としています。

0
windmaomao