Проблема

В 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 Saga test ›должен 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-saga ?

13
Dimitri Kopriwa 13 Мар 2018 в 21:11

2 ответа

Лучший ответ

Если вы отметите эффект саги delay code, вы можете видеть, что это связанная функция:

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

Поэтому, если вы импортируете delay в двух разных модулях, это будут две разные функции, не имеющие визуального различия .

Вы можете проверить это в примере codeandbox (см. Вкладку test):

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

Результат: введите описание изображения здесь

Чтобы проверить свою сагу, вы должны имитировать свой эффект 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
Sergey 5 Июн 2019 в 07:22

Хороший способ проверить вызовы 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));
  });
});

Это работает, потому что результатом yield to call является простой объект, описывающий вызов функции 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();
  });
});
9
Fela Maslen 12 Окт 2018 в 22:18