单元测试Redux异步操作

时间:2017-05-15 18:24:13

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

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

我尝试了thisthis& this

我在我的行动中使用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();
    })

  })

我正在使用nockredux-mock-store配置了thunkpromise middleware

它提供then of undefined

然后我更改了操作以返回promise,然后我得到unhandled promise reject异常,我在action dispatch调用中添加了一个catch。 现在我得到Network Error,因为诺克并没有嘲笑这个电话。 还尝试了moxios,将axios更改为isomorphic-fetchwhatwg-fetch。似乎没有工作

我在哪里做错了?。

2 个答案:

答案 0 :(得分:0)

Since this is an asynchronous action you need to dispatch an success action when the axios post request promise successfully resolves.

You need to return the promise returned by calling axios.post so that you can make the asynchronous assertion in your test.

export function deleteCommand(id) {
  return (dispatch) => {
    dispatch({ type:'DELETE_COMMAND_POSTED' })

    return axios.post(`${Config.apiUrl}delete`, { _id: id })
       .then((res) => {
         dispatch({ type: 'DELETE_SUCCESSFUL', payload: res })
      })
  }
}

答案 1 :(得分:0)

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

所以问题在于bar()
中的箭头函数返回未定义。 这就是为什么您得到

然后给出未定义的

TLDR: 如果您将redux-thunk与redux-promise-middleware一起使用 您必须返回内部调度程序

here is the official redux-promise-middleware docs

解决方案非常简单:
选项1。 在箭头功能内添加返回

deleteCommand

选项2。 从箭头功能中删除花括号

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

现在您可以做到

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

常规箭头功能并返回

  • 返回普通对象
store.deleteCommand(<some id>).then(...)