Jasmine:如何测试返回另一个函数的函数?

时间:2015-08-26 19:44:41

标签: javascript unit-testing jasmine

以下解决方案

问题说明了一切。鉴于此功能:

export function fetchBuilds() {
  return dispatch => {
    touchCookie();
    dispatch(requestBuilds());
    return request.get('/builds')
      .withCredentials()
      .use(AuthIntercept)
      .then((response) => {
        dispatch(receiveBuilds(response));
      }, (error) => {
        dispatch(receiveBuildsError(error.message));
      });
  };
}

什么是最有效的测试策略?我打算嘲笑AJAX请求,但是如何断言返回是我期望的呢?

紧随其后,我也对测试该功能的控制流程的最佳方法感到茫然;或者甚至是我应该担心的事情?

基于@ bkonkle建议的解决方案

setTimeout电话很难看,但他们似乎完成了工作。

describe('Build actions', () => {
  const testBuilds = [
    {id: 1, name: 'some name'}
  ];

  beforeEach(() => {
    dispatchSpy = jasmine.createSpy('dispatch').and.callFake((cb) => {
      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', () => {
    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(() => {
      expect(dispatchSpy).toHaveBeenCalledWith(actions.receiveBuilds(testBuilds));
      setTimeout(() => {
        expect(receiveSpy).toHaveBeenCalledWith(testBuilds);
      }, 10);
    }, 1);
  });
});

1 个答案:

答案 0 :(得分:1)

这绝对不是一件容易测试的事情。我将Sinon用于间谍和存根,并使其成为异步测试。首先,我会在我的测试体中调用返回的函数。我会监视touchCookie,dispatch和requestBuilds,并确保它们被调用。我确保返回函数的返回值是一个promise,并在测试体中附加一个.then,它检查调用sendBuilds和receiveBuildsError的结果调用了调度,两者都是stub。我也会监视Ajax调用并确保请求正确的URL。

你的测试代码肯定比你的实际功能更长,但这并不是一件坏事。 : - )