title: Jasmine: How to test a function which returns another function?
body: <h2>Solution below</h2>
  
  <p>Question says it all.  Given this function:</p>
  
  <pre><code>export function fetchBuilds() {
    return dispatch =&gt; {
      touchCookie();
      dispatch(requestBuilds());
      return request.get('/builds')
        .withCredentials()
        .use(AuthIntercept)
        .then((response) =&gt; {
          dispatch(receiveBuilds(response));
        }, (error) =&gt; {
          dispatch(receiveBuildsError(error.message));
        });
    };
  }
  </code></pre>
  
  <p>what's the most effective testing strategy?  I plan on mocking the AJAX request, but how do I assert that the return is what I expect?</p>
  
  <p>Following on the heels of that, I'm also at a loss as to the best way to test the control flow for the function; or is that even something I should worry about?</p>
  
  <h1>Solution based on @bkonkle's suggestion</h1>
  
  <p>The <code>setTimeout</code> calls are ugly, but they seem to get the job done.</p>
  
  <pre><code>describe('Build actions', () =&gt; {
    const testBuilds = [
      {id: 1, name: 'some name'}
    ];
  
    beforeEach(() =&gt; {
      dispatchSpy = jasmine.createSpy('dispatch').and.callFake((cb) =&gt; {
        switch (cb.type) {
        case types.REQUEST_BUILDS:
          return {
            type: types.REQUEST_BUILDS
          };
  
        case types.RECEIVE_BUILDS:
          return {
            type: types.RECEIVE_BUILDS,
            builds: testBuilds
          };
  
        default:
          return null;
        }
      });
  
      cookieSpy = spyOn(userActions, 'touchCookie');
      requestSpy = spyOn(actions, 'requestBuilds').and.callThrough();
      receiveSpy = spyOn(actions, 'receiveBuilds').and.callThrough();
    });
  
    it('should be able fetch builds', () =&gt; {
      jasmine.Ajax.install();
      const result = actions.fetchBuilds();
      result(dispatchSpy);
  
      expect(cookieSpy).toHaveBeenCalled();
      expect(dispatchSpy).toHaveBeenCalledWith(actions.requestBuilds());
      expect(requestSpy).toHaveBeenCalled();
  
      let request = jasmine.Ajax.requests.mostRecent();
      expect(request.url).toBe(`/builds`);
      request.respondWith({
        status: 200,
        contentType: 'application/json',
        responseText: JSON.stringify(testBuilds)
      });
  
      setTimeout(() =&gt; {
        expect(dispatchSpy).toHaveBeenCalledWith(actions.receiveBuilds(testBuilds));
        setTimeout(() =&gt; {
          expect(receiveSpy).toHaveBeenCalledWith(testBuilds);
        }, 10);
      }, 1);
    });
  });
  </code></pre>