title: How to test a redux-thunk action that contains multiple API requests and array transformations?
body: <p>I have a redux-thunk action that contains multiple API-requests that take data fetched from one endpoint to fetch other relevant data from a different endpoint and I also have a couple of array transformations to merge some of the data together. </p>
  
  <p>Although I'm not sure if this is the best practice, for now, it does what I need. However, it has been difficult to test as I'm not sure what the correct approach is to test it. I have scoured the internet and looked at many different variations of "thunk" tests but mine is failing with every approach so far. </p>
  
  <p>I will really appreciate some guidance on how to test a thunk action such as mine or perhaps better practices in implementing what I have if it makes testing easier. </p>
  
  <p>My thunk-Action...</p>
  
  <pre><code>export const fetchTopStreamsStartAsync = () =&gt; {
    return async dispatch =&gt; {
      try {
        const headers = {
          'Client-ID': process.env.CLIENT_ID
        };
        const url = 'https://api.twitch.tv/helix/streams?first=5';
        const userUrl = 'https://api.twitch.tv/helix/users?';
        let userIds = '';
        dispatch(fetchTopStreamsStart());
  
        const response = await axios.get(url, { headers });
        const topStreams = response.data.data;
  
        topStreams.forEach(stream =&gt; (userIds += `id=${stream.user_id}&amp;`));
        userIds = userIds.slice(0, -1);
  
        const userResponse = await axios.get(userUrl + userIds, { headers });
        const users = userResponse.data.data;
  
        const completeStreams = topStreams.map(stream =&gt; {
          stream.avatar = users.find(
            user =&gt; user.id === stream.user_id
          ).profile_image_url;
          return stream;
        });
  
        const mappedStreams = completeStreams.map(
          ({ thumbnail_url, ...rest }) =&gt; ({
            ...rest,
            thumbnail: thumbnail_url.replace(/{width}x{height}/gi, '1280x720')
          })
        );
  
        dispatch(fetchTopStreamsSuccess(mappedStreams));
      } catch (error) {
        dispatch(fetchTopStreamsFail(error.message));
      }
    };
  };
  </code></pre>
  
  <p>One of the many test approaches that have failed...</p>
  
  <pre><code>import configureMockStore from 'redux-mock-store';
  import thunk from 'redux-thunk';
  import axios from 'axios';
  import moxios from 'moxios';
  
  import {
    fetchTopStreamsStart,
    fetchTopStreamsSuccess,
    fetchTopStreamsStartAsync
  } from './streams.actions';
  
  const mockStore = configureMockStore([thunk]);
  
  describe('thunks', () =&gt; {
    describe('fetchTopStreamsStartAsync', () =&gt; {
      beforeEach(() =&gt; {
        moxios.install();
      });
  
      afterEach(() =&gt; {
        moxios.uninstall();
      });
      it('creates both fetchTopStreamsStart and fetchTopStreamsSuccess when api call succeeds', () =&gt; {
        const responsePayload = [{ id: 1 }, { id: 2 }, { id: 3 }];
  
        moxios.wait(() =&gt; {
          const request = moxios.requests.mostRecent();
          request.respondWith({
            status: 200,
            response: responsePayload
          });
        });
  
        const store = mockStore();
  
        const expectedActions = [
          fetchTopStreamsStart(),
          fetchTopStreamsSuccess(responsePayload)
        ];
  
        return store.dispatch(fetchTopStreamsStartAsync()).then(() =&gt; {
          // return of async actions
          expect(store.getActions()).toEqual(expectedActions);
        });
      });
    });
  });
  </code></pre>
  
  <p>This is the error i'm getting in the failed test for the received value...</p>
  
  <pre><code>+     "payload": "Cannot read property 'forEach' of undefined",
      +     "type": "FETCH_TOP_STREAMS_FAIL",
  </code></pre>
  
  <p><strong>UPDATE:</strong> As @mgarcia suggested i changed the format of my <code>responsePayload</code> from <code>[{ id: 1 }, { id: 2 }, { id: 3 }]</code> to <code>{ data: [{ id: 1 }, { id: 2 }, { id: 3 }] }</code> and now I'm not getting the initial error but now I'm receiving the following error:</p>
  
  <pre><code>: Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.Error:
  </code></pre>
  
  <p>What I still don't understand is does the test have to replicate the exact structure of the multiple API calls or that just mocking one response is enough? I'm still trying to figure out the cause of the <code>Async callback...</code> error.  </p>