Search code examples
javascriptunit-testingreactjsreduxnock

How do we mock fetch for Redux Async Actions?


In the Writing Tests section of Redux, how does the store.dispatch(actions.fetchTodos()) not invoke the fetch method, if store.dispatch is literally calling actions.fetchTodos?

it('creates FETCH_TODOS_SUCCESS when fetching todos has been done', (done) => {
    nock('http://example.com/')
      .get('/todos')
      .reply(200, { todos: ['do something'] })

    const expectedActions = [
      { type: types.FETCH_TODOS_REQUEST },
      { type: types.FETCH_TODOS_SUCCESS, body: { todos: ['do something']  } }
    ]
    const store = mockStore({ todos: [] }, expectedActions, done)
    store.dispatch(actions.fetchTodos())
})

Solution

  • It is calling the fetch method, but the nock line:

    nock('http://example.com/')
      .get('/todos')
      .reply(200, { todos: ['do something'] })
    

    stubs out the HTTP request so that fetch simply returns the right data (without actually hitting the endpoint).

    Another option is to extract the call to fetch into another module — say, api — and use it inside your action creator. In tests, you would simply mock out the appropriate methods on the api module.