简体   繁体   English

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

[英]Testing Flux store with async api using Jasmine

I'm trying to test some very simple functionality with Flux store that on specific event call to service that make http request and return Promise , store looks like: 我正在尝试使用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);
      });

For the testing I'm using Jasmine , and my test case looks like: 对于测试,我使用的是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);
})

As expected this test if failed, because of asynchronous behavior of Promise , I'm understand the problem here but I'm can not find solution how to say to test wait until Promise from userService resolved. 如预期的那样,该测试失败了,因为Promise的异步行为,我在这里理解了问题,但是我找不到解决方法该说如何测试直到userService Promise解决。

I would not recommend using async calls inside the store. 我不建议在商店内部使用异步调用。 It can lead to an unpredictable state of the store. 这可能导致商店的状态无法预测。 And probably you may have this error: Flux Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch . 可能您会遇到以下错误: Flux Dispatch.dispatch(...):无法在调度中间进行调度

Instead, your userService should handleAction with the user data, once the user fetched. 取而代之的是,一旦提取了用户,则userService应该使用用户数据处理handleAction And your store should update then the user data. 并且您的商店应该先更新用户数据。

For example, 例如,

User service: 用户服务:

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

User store: 用户商店:

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

Here is a good short article about fetching data with API and Flux: https://medium.com/@tribou/flux-getting-data-from-an-api-b73b6478c015#.vei6eq5gt 这是一篇有关使用API​​和Flux获取数据的简短文章: https : //medium.com/@tribou/flux-getting-data-from-an-api-b73b6478c015#.vei6eq5gt

Then, you can write tests separately for your stores and services: 然后,您可以为商店和服务分别编写测试:

Store Test: 商店测试:

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);
})

Service Test: 服务测试:

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
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM