Testing dispatched actions in Redux thunk with Jest

前端 未结 4 773
栀梦
栀梦 2020-12-15 07:33

I\'m quite new to Jest and admittedly am no expert at testing async code...

I have a simple Fetch helper I use:

export function fetchHe         


        
4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-15 08:22

    In my answer I am using axios instead of fetch as I don't have much experience on fetch promises, that should not matter to your question. I personally feel very comfortable with axios.
    Look at the code sample that I am providing below:

    // apiCalls.js
    const fetchHelper = (url) => {
      return axios.get(url);
    }
    
    
    import * as apiCalls from './apiCalls'
    describe('getSomeData', () => {
      it('should dispatch SET_LOADING_STATE on start of call', async () => {
        spyOn(apiCalls, 'fetchHelper').and.returnValue(Promise.resolve());
        const mockDispatch = jest.fn();
    
        await getSomeData()(mockDispatch);
    
        expect(mockDispatch).toHaveBeenCalledWith({
          type: SET_LOADING_STATE,
          value: true,
        });
      });
    
      it('should dispatch SET_DATA action on successful api call', async () => {
        spyOn(apiCalls, 'fetchHelper').and.returnValue(Promise.resolve());
        const mockDispatch = jest.fn();
    
        await getSomeData()(mockDispatch);
    
        expect(mockDispatch).toHaveBeenCalledWith({
          type: SET_DATA,
          value: { ...},
        });
      });
    
      it('should dispatch SET_FAIL action on failed api call', async () => {
        spyOn(apiCalls, 'fetchHelper').and.returnValue(Promise.reject());
        const mockDispatch = jest.fn();
    
        await getSomeData()(mockDispatch);
    
        expect(mockDispatch).toHaveBeenCalledWith({
          type: SET_FAIL,
        });
      });
    });
    

    Here I am mocking the fetch helper to return Resolved promise to test success part and reject promise to test failed api call. You can pass arguments to them to validate on response also.
    You can implement getSomeData like this:

    const getSomeData = () => {
      return (dispatch) => {
        dispatch(setLoading(true));
        return fetchHelper('http://datasource.com/')
          .then(response => {
            dispatch(setData(response.data));
            dispatch(setLoading(false));
          })
          .catch(error => {
            dispatch(setFail());
            dispatch(setLoading(false));
          })
      }
    }
    

    I hope this solves your problem. Please comment, if you need any clarification.
    P.S You can see by looking at above code why I prefer axios over fetch, saves you from lot of promise resolves!
    For further reading on it you can refer: https://medium.com/@thejasonfile/fetch-vs-axios-js-for-making-http-requests-2b261cdd3af5

提交回复
热议问题