测试redux-saga的“ all”效果的最佳方法是什么?

时间:2018-06-19 22:30:19

标签: testing redux-saga

我有一个传说,当前有一个yield all(...),我想弄清楚如何测试以查看我实际上是在使用正确的功能来调用all()。这是我正在使用的简化版本:

function* start() {
  // I'd prefer not to start the status polling and the listening for
  // the cancellation until after the request has been submitted, but
  // I'm having trouble figuring out how to do that. So I'm just going
  // to listen for 'em all up front here until I'm smarter.
  yield all([
    waitForCreateRequest(),
    waitForPollStatus(),
    waitForCancelRequest(),
  ])
}

function* waitForCreateRequest() {
  while ( true ) {  
    try {
      const { payload } = yield take('CREATE_REQUEST')
      // ...
    } catch ( error ) {
      // ...
    }
  }
}

function* waitForPollStatus() {
  while ( true ) {  
    try {
      const { payload } = yield take('POLL_STATUS')
      // ...
    } catch ( error ) {
      // ...
    }
  }
}

function* waitForCancelRequest() {
  while ( true ) {  
    try {
      yield take('CANCEL_REQUEST')
      // ...
    } catch ( error ) {
      // ...
    }
  }
}

我编写的测试(使用Mocha和bdd-lazy-var)如下:

describe('MySaga', () => {
  describe('*start()', () => {
    subject(start())

    it('calls `all()` with the correct functions', () => {
      expect($subject.next().value).to.eql(all([
        waitForSubmitExportRequest(),
        waitForPollExportStatus(),
        waitForCancelExportRequest(),
      ]))
    })
  })
})

没有输出-它只是挂起...然后出现“ JavaScript堆内存不足”错误。

如果我改为console.log($subject.next().value)

describe('MySaga', () => {
  describe('*start()', () => {
    subject(start())

    it.only('foo', () => {
      console.log($subject.next().value)
    })
  })
})

这就是我得到的:

  MySaga
    *start()
{ '@@redux-saga/IO': true,
  ALL: 
   [ GeneratorFunctionPrototype { _invoke: [Function: invoke] },
     GeneratorFunctionPrototype { _invoke: [Function: invoke] },
     GeneratorFunctionPrototype { _invoke: [Function: invoke] } ] }
      ✓ foo

所以我不确定这是怎么回事。

无数的Google搜索并没有发现任何有用的信息,而我发现的最接近的SO帖子(how to test redux-saga all effect using jest)也无济于事。

1 个答案:

答案 0 :(得分:3)

您的start函数不是生成器函数是否是错字?

无论如何。您能否尝试像这样重写start函数:

function* start() {
  yield all([
    call(waitForCreateRequest),
    call(waitForPollStatus),
    call(waitForCancelRequest),
  ])
}

现在您的测试可能如下:

it('calls `all()` with the correct functions', () => {
  expect($subject.next().value).to.eql(all([
    call(waitForSubmitExportRequest),
    call(waitForPollExportStatus),
    call(waitForCancelExportRequest),
  ]))
})