使用将函数作为模式的 redux-saga-test-plan 进行断言给出 'take effects do not match' 错误

take assertion with redux-saga-test-plan that takes a function as pattern gives 'take effects do not match' error

我想测试一个产生 take 效果的 saga,它将函数作为模式,例如

export function* mySaga(myAction: {
  type: string;
}): Generator<TakeEffect, boolean, { type: string }> {
  const { type: actionType } = (yield take(
    (action: any) => action.type === myAction.type,
  )) as { type: string };
  return actionType === myAction.type;
}

测试看起来像:

it('Should test mySaga', () => {
  testSaga(mySaga, { type: 'myActionType' }).next().take().next().finish();
});

但我收到以下错误:

SagaTestError: 
Assertion 1 failed: take effects do not match

Expected
--------
{ '@@redux-saga/IO': true,
  combinator: false,
  type: 'TAKE',
  payload: { pattern: '*' } }

Actual
------
{ '@@redux-saga/IO': true,
  combinator: false,
  type: 'TAKE',
  payload: { pattern: [Function] } }

我无法找到如何断言采用函数模式而不是字符串的生效。有人可以帮我吗?

由于您将匿名函数传递给 take 效果创建者。我们无法在测试用例中使用 requireing 模块获取此匿名函数。

您可以使用 inspect 通用断言助手。

If your saga yields a nondeterministic type of value or something not easily covered by the effect assertions or other general assertions, then you can use inspect to retrieve the actual yielded value and perform your own assertions with your favorite assertion library.

这样我们就可以得到yield take((action: any) => action.type === myAction.type)的返回效果了。然后断言这个效果。

例如(使用 jestjs 作为测试框架)

saga.ts:

import { TakeEffect, take } from 'redux-saga/effects';

export function* mySaga(myAction: { type: string }): Generator<TakeEffect, boolean, { type: string }> {
  const { type: actionType } = (yield take((action: any) => action.type === myAction.type)) as { type: string };
  console.log('actionType: ', actionType);
  return actionType === myAction.type;
}

saga.test.ts:

import { testSaga } from 'redux-saga-test-plan';
import { TakeEffect } from 'redux-saga/effects';
import { mySaga } from './saga';

describe('63523200', () => {
  it('should pass', () => {
    testSaga(mySaga, { type: 'myActionType' })
      .next()
      .inspect<TakeEffect>((yieldedValue) => {
        expect(yieldedValue.payload.pattern).toEqual(expect.any(Function));
        // test this anonymous function
        expect((yieldedValue.payload.pattern as Function)({ type: 'myActionType' })).toBeTruthy();
        expect((yieldedValue.payload.pattern as Function)({ type: 'hisActionType' })).toBeFalsy();
      })
      .next({ type: 'otherActionType' })
      .isDone();
  });
});

单元测试结果:

 PASS  src/Whosebug/63523200/saga.test.ts
  63523200
    ✓ should pass (23 ms)

  console.log
    actionType:  otherActionType

      at src/Whosebug/63523200/saga.ts:5:11

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 saga.ts  |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.809 s, estimated 3 s