【问题标题】:How to test functional selectors in redux saga?如何在 redux saga 中测试功能选择器?
【发布时间】:2017-08-18 08:13:36
【问题描述】:

目前可以像这样编写 reducer 和测试 saga:

// selector
const selectThingById = (state, id) => state.things[id]

// in saga
const thing = yield select(selectThingById, id)

// and test
expect(gen.next().value)
  .toEqual(select(selectThingById, id))

但是我想使用更实用的方法来编写我的 reducer 并将数据(状态)放在参数的最后:

// selector
const selectThingById = R.curry((id, state) => state.things[id])

// in saga
const thing = yield select(selectThingById(id))

// test: this actually fails
expect(gen.next().value)
  .toEqual(select(selectThingById(id)))

测试失败,因为selectThingById(id) 每次都创建新函数。

这可以通过将参数添加到select 而不是追加来解决。是否有可能或有什么方法可以测试这样的选择器?

【问题讨论】:

    标签: javascript redux jestjs redux-saga ramda.js


    【解决方案1】:

    您需要使用 call 效果调用选择器工厂,以便您可以使用 gen.next(val) 将正确的函数注入到 saga 中

    // in saga
    const selector = yield call(selectThingById, id)
    const thing = yield select(selector)
    
    // test
    const selector = selectThingById(id)
    gen.next(selector)
      .toEqual(call(selectThingById, id))
    expect(gen.next().value)
      .toEqual(select(selector))
    

    【讨论】:

    • 不错的解决方案!最好有一些实用功能。
    • 这绝对是正确的方法。对于刚接触 saga 的开发人员(包括我自己)来说,一个常见的陷阱是我们通过直接调用函数在 saga 内部创建了副作用。这导致 sagas 很难测试。请记住使用call 效果,以便 saga 始终承诺做某事,但直到由 saga 中间件执行后才执行。
    【解决方案2】:

    只需导出您的函数以在您的测试中导入并将其放入next

    // selector
    export const selectThingById = R.curry((id, state) => state.things[id])
    
    // in saga
    const thing = yield select(selectThingById(id))
    
    // test
    expect(gen.next(selectThingById).value)
      .toEqual(select(selectThingById(id)))
    

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 2017-04-07
      • 2017-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多