如何使用 redux-saga-test-plan 测试选择器功能

How to test selector function with redux-saga-test-plan

我正在测试我的 redux-saga-flow,我在测试 select 或使用 select 的方法时遇到问题。

选择器

const selector = (state) => {
   console.log("selector");
   return data;
}

Redux 传奇流程

export function* testedSagaFlow() {
  const data = yield select(selector);
  if (!data) {
    return;
  }
  yield put (otherAction)
  ...
}

流量测试

test("Get data from store", () => {
  return expectSaga(testedSagaFlow)
  .provide([[mathchers.select.selector(selector), null]])
  .select(selector)
  .not.put(otherAction)
  .run()
})

经过运行一个测试,一个没有console.log("selector");而且这行代码也没有被测试覆盖

如何测试 select 或?

同样不适用于单元测试。

test("Unit test flow", () => {
   const saga = testSaga(testedSagaFlow);
   saga
    .next()
    .select(selector)
    .next(null)
    .isDone()
})

"redux-saga-test-plan": "^4.0.1".

选项 1. 使用 withState:

For static state, you can just use the withState method to allow select effects to work.

选项 2. 使用 static provider

You can provide mock values in a terse manner via static providers. Pass in an array of tuple pairs (array pairs) into the provide method. For each pair, the first element should be a matcher for matching the effect and the second effect should be the mock value you want to provide.

例如

saga.ts:

import { put, select } from 'redux-saga/effects';

const otherAction = { type: 'OTHER_ACTION' };

export const selector = (state) => {
  console.log('selector');
  return state.data;
};

export function* testedSagaFlow() {
  const data = yield select(selector);
  if (!data) {
    return;
  }
  yield put(otherAction);
}

saga.test.ts:

import { expectSaga } from 'redux-saga-test-plan';
import { select } from 'redux-saga/effects';
import { selector, testedSagaFlow } from './saga';

describe('70199170', () => {
  test('should dispatch other action', () => {
    const state = { data: true };
    return expectSaga(testedSagaFlow).withState(state).put({ type: 'OTHER_ACTION' }).run();
  });

  test('should return if data is nil', () => {
    const state = { data: null };
    return expectSaga(testedSagaFlow).withState(state).not.put({ type: 'OTHER_ACTION' }).run();
  });
});

describe('70199170 - use provider', () => {
  test('should dispatch other action', () => {
    return expectSaga(testedSagaFlow)
      .provide([[select(selector), true]])
      .put({ type: 'OTHER_ACTION' })
      .run();
  });

  test('should return if data is nil', () => {
    return expectSaga(testedSagaFlow)
      .provide([[select(selector), null]])
      .not.put({ type: 'OTHER_ACTION' })
      .run();
  });
});

测试结果:

 PASS   redux-saga-examples  packages/redux-saga-examples/src/Whosebug/70199170/saga.test.ts
  70199170
    ✓ should dispatch other action (30 ms)
    ✓ should return if data is nil (4 ms)
  70199170 - use provider
    ✓ should dispatch other action (2 ms)
    ✓ should return if data is nil (3 ms)

  console.log
    selector

      at selector (packages/redux-saga-examples/src/Whosebug/70199170/saga.ts:6:11)

  console.log
    selector

      at selector (packages/redux-saga-examples/src/Whosebug/70199170/saga.ts:6:11)

Test Suites: 1 passed, 1 total
Tests:       4 passed, 4 total
Snapshots:   0 total
Time:        2.934 s, estimated 3 s
Ran all test suites related to changed files.