使用Jasmine使用异步api测试Flux存储

时间:2016-08-03 18:12:57

标签: javascript unit-testing reactjs jasmine flux

我正在尝试使用Flux存储测试一些非常简单的功能,在特定事件调用服务时发出http请求并返回Promise,存储看起来像:

case UserActions.FETCH_USER_BY_ID:
   const userService = new UserService();
   userService.fetchUserById(action.id)
      then(user => {
        this.user = user;
        this.emit(USER_FETCH_COMPLETED);
      });

对于我正在使用Jasmine的测试,我的测试用例如下:

it('should fetch user by id', () => {
  const userStore = require('../stores/userStore');
  const mockUser = {name: 'test', id: 123};
  spyOn(UserService.prototype, 'fetchUserById')
    .and.returnValue(Promise.resolve(mockUser));
  dispatchEvent();
  expect(userStore.user).toEqual(mockUser);
})

正如预期的那样,这个测试如果失败了,因为Promise的异步行为,我在这里理解这个问题但是我找不到解决方法如何测试等到Promise来自{ {1}}已解决。

1 个答案:

答案 0 :(得分:1)

我不建议在商店内使用异步调用。它可能导致商店的不可预测状态。可能您可能会遇到此错误:Flux Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch

相反,一旦用户抓取,您的userService应该handleAction使用用户数据。您的商店应该更新用户数据。

例如,

用户服务:

userService.fetchUserById = function(userId) {
  apiCall(userId).then(user => handleAction(UserActions.FETCH_USER_BY_ID, user));
}

用户商店:

   case UserActions.FETCH_USER_BY_ID:
     this.user = payload.data;
     this.emit(USER_FETCH_COMPLETED);
     break;

这是一篇关于使用API​​和Flux获取数据的简短文章: https://medium.com/@tribou/flux-getting-data-from-an-api-b73b6478c015#.vei6eq5gt

然后,您可以分别为您的商店和服务编写测试:

商店测试:

it('should fetch user by id', () => {
  const userStore = require('../stores/userStore');
  const mockUser = {name: 'test', id: 123};
  handleAction(UserActions.FETCH_USER_BY_ID, mockUser) 
  expect(userStore.user).toEqual(mockUser);
})

服务测试:

it('should fetch user by id', (done) => {
  const userService = require('../service/userService');
  // userService.fetchUserById(userId);
  // here you can add spyOn http service that you are using in the service
  // and mock the response from that service
  // and then validate that `handleAction` has been triggered
})