从数据库调度数据的 Redux 动作的单元测试

Unit test for Redux action which dispatches data from database

我有如下操作

index.js

export const dataCount = () => {
  return async (dispatch) => {
    getDataCount().then((data) => {
      dispatch({ type: 'FETCH_DATA_COUNT', payload: data});
    });
  };
};

这里的 getDataCount 是一个辅助函数,returns 承诺从数据库中获取数据。

暂时我的测试是这样的

import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import dataCount from '../index';
import getDataCount from '../helper';
    
const middlewares = [thunk];
const mockStore = configureStore(middlewares);
const store = mockStore();
let dataValue = '';

describe('fetchData', () => {
  beforeEach(() => { // Runs before each test in the suite
    dataValue = jest.fn(getDataCount);
    store.clearActions();
  });

  it('has the correct action and payload for dataCount', async () => {
    dataValue .mockReturnValue({ total : 13 });
    const expectedActions = [
      {
        payload: dataValue(),
        type: 'FETCH_DATA_COUNT'
      }
    ];
    await getDataCount().then((res) => {
        store.dispatch(dataCount());
        expect(store.getActions()).toEqual(expectedActions);
    });
  });
});

测试失败,因为 store.getActions() 返回 [],我知道我在调度时做错了什么。任何建议都会有很大帮助。

有一些事情我们可以通过这个测试做得更好。

你的 action creator 应该 return 我们在里面使用的 promise。如果我们这样做,我们可以将事情链接到调度上,以便在异步操作完成后发生。你的已经 return 一个承诺,因为它的 async 关键字,但这可能会导致时间问题。

export const dataCount = () => {
  return async (dispatch) => {
    return getDataCount().then((data) => {
      dispatch({ type: 'FETCH_DATA_COUNT', payload: data });
    });
  };
};

第二个更改是将我们在测试中的断言链接到测试代码的调度后面。所以我们等待调度完全解决,然后比较动作。

it('has the correct action and payload for dataCount', async () => {
  const expectedActions = [
    {
      payload: { total: 13 },
      type: 'FETCH_DATA_COUNT'
    }
  ];
  // await the whole promise chain for jest to know how long to wait
  await store.dispatch(dataCount())
    .then(() => { // dispatch is resolved here
      expect(store.getActions()).toEqual(expectedActions)
    })
});

第三件事,dataValue mock 并没有按照你的想法去做。要模拟此功能,您必须依赖注入它。在最简单的情况下,将它作为参数提供给 dataCount

store.dispatch(dataCount(dataValue))

依赖注入对您的单元测试很有用,因为现在测试将进入网络或任何地方 getDataCount 这会使您的测试变慢并且容易出错。

如果我有任何未解决的问题或错误,请告诉我。