【问题标题】:Unit testing Redux async actions单元测试 Redux 异步操作
【发布时间】:2017-10-14 15:29:36
【问题描述】:

我正在尝试将单元测试用例添加到我的 redux 操作中。

我试过thisthisthis

我在操作中使用thunkpromise-middleware

我的一个动作是这样的

export function deleteCommand(id) {
  return (dispatch) => {
    dispatch({
      type: 'DELETE_COMMAND',
      payload: axios.post(`${Config.apiUrl}delete`, { _id: id })
    })
  }
}

对此进行单元测试

import configureMockStore from "redux-mock-store"
const middlewares = [thunk, promiseMiddleware()];
const mockStore = configureMockStore(middlewares)

  it('creates DELETE_COMMAND_FULFILLED after deleting entry', (done) => {

    nock('http://localhost:8081/')
      .post('/delete',{
        _id: 1
      })
      .reply(200, {})

    const expectedActions = [{
      type: 'DELETE_COMMAND_FULFILLED',
      payload: {}
    }]

    const store = mockStore({
      command: {
        commands: []
      }
    })

    store.dispatch(actions.deleteCommand({_id: 1}).then(function () {
      expect(store.getActions())
        .toEqual(expectedActions)
      done();
    })

  })

我正在使用nock,redux-mock-store 配置有thunk,promise middleware

它给then of undefined

然后我更改了动作以返回承诺,然后我得到unhandled promise reject 异常,我在动作调度调用中添加了一个catch。 现在我收到了Network Error,因为 nock 没有在模拟通话。 也试过moxios,把axios改成isomorphic-fetchwhatwg-fetch。好像不行

我哪里做错了?

【问题讨论】:

  • 您是否正确配置了模拟商店?即添加 thunk 和 promise 中间件。
  • 我也用模拟商店更新了我的问题

标签: javascript unit-testing redux redux-thunk nock


【解决方案1】:

我知道这是从 2017 年开始的, 但也许有人会遇到同样的问题。

所以问题是deleteCommand
内部的箭头函数返回未定义。 这就是你得到的原因

然后给出未定义的

TLDR: 如果你使用 redux-thunk 和 redux-promise-middleware 你必须返回内部调度

here is the official redux-promise-middleware docs

解决方案非常简单:
选项 1. 在箭头函数内添加return

    export function deleteCommand(id) {
      return (dispatch) => {
        return dispatch({
          type: 'DELETE_COMMAND',
          payload: axios.post(`${Config.apiUrl}delete`, { _id: id })
        })
      }
    }

选项 2。 删除箭头函数中的花括号

export function deleteCommand(id) {
  return (dispatch) => 
    dispatch({
      type: 'DELETE_COMMAND',
      payload: axios.post(`${Config.apiUrl}delete`, { _id: id })
    })
}

现在你可以做

store.deleteCommand(<some id>).then(...)

一般的箭头函数和返回

  • 返回一个普通对象
// option 1
const arrowFuncOne = () => {
  return {...someProps}
}

// option 2
const arrowFuncTwo = () => ({
   ...someProps
})

// This means that you returning an expression 
//same as

// return a result of other function
const arrowFuncCallFunOne = () => callSomeOtherFunc()
// or
const arrowCallFunkTwo = () => {return callSomeOtherFunc()}


// However
// wrong 
const arrowCallFunkNoReturn = () => {callSomeOtherFunc()}
// in this case the curly braces are just the body of the function  
// and inside this body there is no return at all

【讨论】:

    猜你喜欢
    • 2012-05-20
    • 1970-01-01
    • 2014-02-27
    • 2017-03-04
    • 2017-03-03
    • 2019-10-31
    • 2019-11-12
    相关资源
    最近更新 更多