redux-saga-test-plan放置效果不匹配,但实际负载和预期负载相同

时间:2019-02-26 12:28:46

标签: reactjs redux jestjs saga redux-saga-test-plan

我正在测试这个传奇

export function* foo() {
  yield put(actions.start());
  yield put(actions.bar({
    onSuccess: () => {
      // do something
    },
    onFailed: () => {
      // do something else
    }
  }));
  yield put(userActions.done());
}

这是我的测试

it('should test foo saga, and put start, bar and done actions', () => {
  // assertions / expect
  testSaga(sagas.foo)
    .next()
    .put(actions.start())
    .next()
    .put(
      actions.bar({
        onSuccess: () => {},
        onFailed: () => {},
      }),
    )
    .next()
    .put(actions.done())
    .next()
    .isDone();
});

当我从传奇中删除有效负载并测试它通过时没有问题,但是当我添加有效负载(不仅是onSuccess和onFailed回调的任何内容)时,它都会向我显示此错误

Assertion failed: put effects do not match

Expected
--------
{
  channel: null,
  action: 
   { type: 'BAR',
     payload: 
      {
        onSuccess: [Function: onSuccess],
        onFailed: [Function: onFailed]
      }
  }
}

Actual
------
{
  channel: null,
  action: 
   { type: 'BAR',
     payload: 
      {
        onSuccess: [Function: onSuccess],
        onFailed: [Function: onFailed]
      }
  }
}

有趣的是,实际有效载荷和预期有效载荷相等,但是测试未通过!

1 个答案:

答案 0 :(得分:0)

onSuccessonFailed 方法在 saga 和测试用例中有不同的引用。断言肯定会失败。

由于您在 saga 中声明了这两个方法,因此我们无法通过模块要求将它们导入到我们的测试用例中。因此,我们无法在我们的测试用例中使用这两种方法的相同引用。

我们可以使用 redux-saga-test-plan 提供的 inspect 一般断言。

<块引用>

如果您的 saga 产生非确定性类型的值或效果断言或其他一般断言不易涵盖的内容,那么您可以使用 inspect 检索实际产生的值并使用您最喜欢的断言执行您自己的断言图书馆。

我们用它来得到yield put(actions.bar({...}))的返回效果。然后,我们可以在测试用例中获取由 actions.bar({...}) 创建的 redux action 包括 onSuccessonFailed 方法,以及您在 actions.bar() action creator 中传递的所有内容} 传奇。

我们可以使用 jestjs 提供的 foo 来断言这两个方法。您甚至可以执行和测试它们。

例如

expect.any(Function)

saga.ts

import { put } from 'redux-saga/effects'; import * as actions from './actions'; export function* foo() { yield put(actions.start()); yield put( actions.bar({ onSuccess: () => { // do something }, onFailed: () => { // do something else }, }), ); yield put(actions.done()); }

saga.test.ts

单元测试结果:

import { testSaga } from 'redux-saga-test-plan';
import { foo } from './saga';
import * as actions from './actions';
import { PutEffect } from 'redux-saga/effects';
import { AnyAction } from 'redux';

describe('54885611', () => {
  it('should pass', () => {
    const logSpy = jest.spyOn(console, 'log');
    testSaga(foo)
      .next()
      .put(actions.start())
      .next()
      .inspect<PutEffect<AnyAction>>((yieldedValue) => {
        expect(yieldedValue.payload.action).toEqual({
          type: 'START',
          payload: expect.objectContaining({ onSuccess: expect.any(Function), onFailed: expect.any(Function) }),
        });
        // test onSuccess
        yieldedValue.payload.action.payload.onSuccess();
        expect(logSpy).toBeCalledWith('do something');

        // test onFailed
        yieldedValue.payload.action.payload.onFailed();
        expect(logSpy).toBeCalledWith('do something else');

        logSpy.mockRestore();
      })
      .next()
      .put(actions.done())
      .next()
      .isDone();
  });
});