如何使用redux-saga测试`call(fn,params)`

时间:2018-01-04 21:42:07

标签: javascript unit-testing redux-saga

我在使用redux-saga测试我认为简单的传奇时会看到一些奇怪的结果。 以这个传奇为例:

export function* initSaga() {

  yield call(window.clearTimeout, runner)

  yield call(PubSub.publishSync, 'RESET_CORE')

}

我的测试心理模型读取,首先检查它名为window.clearTimeout,其参数与runner的值匹配,然后使用值'RESET_CORE'测试它称为PubSub的publishSync方法

我对第一部分的测试是:

describe('when testing the init saga', () => {

  const saga = initSaga()
  const runner = null 

  it('first clears the draw loop for the canvas', () => {

    const result = saga.next().value
    const expected = call(window.clearInterval, runner)

    console.log(result)
    console.log(expected)

    expect(result).to.deep.equal(expected)

  })
})

令人沮丧的是错误消息显示为:

AssertionError: expected { Object (@@redux-saga/IO, CALL) } to deeply equal { Object (@@redux-saga/IO, CALL) }

我的控制台日志显示为:

 console.log src\tests\sagas\simulatorSaga.test.js:25
    { '@@redux-saga/IO': true,
      CALL:
       { context: null,
         fn: [Function: bound stopTimer],
         args: [ null ] } }

  console.log src\tests\sagas\simulatorSaga.test.js:26
    { '@@redux-saga/IO': true,
      CALL:
       { context: null,
         fn: [Function: bound stopTimer],
         args: [ null ] } }

对我而言,这看起来完全相同。我假设有一些简单的我在这里缺少,某种深层次的对象参考类型的东西,但我不确定记住这个传奇并测试我怎么能让它再减少。

我知道整个window + pubsub并不完全是如何使用saga的,但应用程序正在与用于运行模拟的画布连接,所以我们有类似的这样做。

1 个答案:

答案 0 :(得分:1)

我知道这是官方文档的建议,但我不喜欢这样的测试。看起来有点像测试redux-saga是否能完成它的工作。您真正感兴趣的是使用正确的参数执行clearIntervalpublishSync。你不关心发电机返回什么。所以这就是我的建议:

const executeSaga = function (saga) {
  var result = saga.next();

  while(!result.done) {
    result = saga.next();
  }
}

describe('when testing the init saga', () => {

  const runner = null;

  it('first clears the draw loop for the canvas', () => {
    sinon.stub(window, 'clearInterval');
    sinon.stub(PubSub, 'publishSync');
    executeSaga(initSaga());

    expect(window.clearInterval)
      .to.be.calledOnce
      .and.to.be.calledWith(runner);

    expect(PubSub.publishSync)
      .to.be.calledOnce
      .and.to.be.calledWith('RESET_CORE');

    window.clearInterval.restore();
    PubSub.publishSync.restore();
  })
})

涉及sinonjs。我们正在对两个函数进行存根,运行整个传奇,然后期望存根。