redux-saga-test-plan put 效果不匹配,但实际和预期的有效负载相等

Posted

技术标签:

【中文标题】redux-saga-test-plan put 效果不匹配,但实际和预期的有效负载相等【英文标题】:redux-saga-test-plan put effects do not match, but payload of actual and expected are equal 【发布时间】:2019-07-20 00:03:44 【问题描述】:

我正在测试这个传奇

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

当我从 saga 中删除有效负载并测试它没有问题通过时,但是当我添加有效负载(不仅是 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】:

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

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

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

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

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

我们可以使用 jestjs 提供的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();
  );
);

单元测试结果:

 PASS  src/***/54885611/saga.test.ts
  54885611
    ✓ should pass (25 ms)

  console.log
    do something

      at console.<anonymous> (node_modules/jest-mock/build/index.js:848:25)

  console.log
    do something else

      at console.<anonymous> (node_modules/jest-mock/build/index.js:848:25)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |     100 |      100 |     100 |     100 |                   
 actions.ts |     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:        3.351 s

【讨论】:

以上是关于redux-saga-test-plan put 效果不匹配,但实际和预期的有效负载相等的主要内容,如果未能解决你的问题,请参考以下文章

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

无法弄清楚如何使用 redux-saga-test-plan 测试 redux-saga 功能

Redux Saga:使用 redux-saga-test-plan 和 jest 在我的 saga 中测试纯 javascript 函数

C语言中put()与puts()的区别?

put与get的区别

java map .put 方法