web-dev-qa-db-ja.com

redux-saga遅延をテストする方法

問題

_redux-saga_では、yield delay(1000);を使用しています。単体テストでは、expect(generator.next().value).toEqual(delay(1000));を実行します。

テストに合格することを期待しています。

これは私の_sagas.js_です。

_import { delay } from 'redux-saga';

export function* incrementAsync() {
  yield delay(1000);
}
_

これは私の_sagas.test.js_です

_import { delay } from 'redux-saga';
import { incrementAsync } from '../sagas';

describe('incrementAsync Saga test', () => {
  it('should incrementAsync', () => {
    const generator = incrementAsync();
    expect(generator.next().value).toEqual(delay(1000));
  });
});
_

●incrementAsync佐賀テスト› incrementAsync

_expect(received).toEqual(expected)

Expected value to equal:
  {"@@redux-saga/CANCEL_PROMISE": [Function anonymous]}
Received:
  {"@@redux-saga/CANCEL_PROMISE": [Function anonymous]}

Difference:

Compared values have no visual difference.
_

質問

redux-sagadelayをテストするにはどうすればよいですか?

8
Dimitri Kopriwa

delay saga effect code を確認すると、バインドされた関数であることがわかります。

export const delay = call.bind(null, delayUtil)

したがって、2つの異なるモジュールにdelayをインポートすると、2つの異なる関数に視覚的な違いがありません

これはコードサンドボックスの例で確認できます([テスト]タブを参照):

Edit redux-saga delay test

const testFunction = () => {};

describe("example bound functions equality test", () => {
  it("Two bound functions are not equal", () => {
    expect(testFunction.bind(this))
      .not.toEqual(testFunction.bind(this));
  });
});

結果は: enter image description here

サガをテストするには、delay効果をモックする必要があります( Jest を使用している場合)。

import { delay } from "redux-saga";
import { incrementAsync } from "../sagas";

jest.mock("redux-saga");

describe("incrementAsync Saga test", () => {
  it("should incrementAsync", () => {
    const generator = incrementAsync();
    expect(generator.next().value).toEqual(delay(1000));
  });
});
8
Anton Novik

Redux Sagaの呼び出しをテストする良い方法は、call効果を使用することです。この場合、次のようにサガを少しリファクタリングできます。

import { delay } from 'redux-saga';
import { call } from 'redux-saga/effects';

export function* incrementAsync() {
  yield call(delay, 1000);
}

次に、次のようにテストします。

import { delay } from 'redux-saga';
import { call } from 'redux-saga/effects';

describe('incrementAsync', () => {
  it('should incrementAsync()', () => {
    const generator = incrementAsync();

    expect(generator.next().value).toEqual(call(delay, 1000));
  });
});

これは、callへのyieldの結果が、delay関数の呼び出しを記述する単純なオブジェクトであるために機能します。モックは必要ありません:)

もちろん素晴らしいredux-saga-test-planヘルパーライブラリ。それを使用すると、テストは次のようになります。

import { testSaga } from 'redux-saga-test-plan';
import { delay } from 'redux-saga';
import { call } from 'redux-saga/effects';

describe('incrementAsync', () => {
  it('should incrementAsync()', () => {
    testSaga(incrementAsync)
      .next()
      .call(delay, 1000)
      .next()
      .isDone();
  });
});
7
Fela Maslen