2

I am trying to add unit test cases to my redux actions.

I have tried this, this & this

I am using thunk, promise-middleware in my actions

one of my action is like this

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

unit test for this is

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();
    })

  })

I am using nock,redux-mock-store configured with thunk, promise middleware

It gives then of undefined

then I changed the action to return the promise, then I got unhandled promise reject exception, I added a catch to the action dispatch call. Now I am getting Network Error because nock is not mocking the call. Also tried moxios, changed axios to isomorphic-fetch, whatwg-fetch. Doesn't seem to be working

Where am I doing it wrong?.

2
  • Are you configuring your mock store correctly? i.e. adding the thunk and promise middleware. Commented May 15, 2017 at 20:54
  • I have updated my question with mock store as well Commented May 16, 2017 at 5:05

1 Answer 1

0

I know It's from 2017, But maybe someone will have the same issue.

So the problem is that the arrow function inside deleteCommand
returns undefined. That's why you get

It gives then of undefined

TLDR: if you using redux-thunk with redux-promise-middleware You must return the inner dispatch

here is the official redux-promise-middleware docs

The solution is very simple :
Option 1. Add return inside the arrow function

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

Option 2. Remove the curly braces from the arrow function

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

Now you can do

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

In general arrow functions and return

  • Return a plain object
// 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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.