如何在React中为异步方法编写单元测试用例?

时间:2019-09-19 13:25:51

标签: react-redux jestjs axios enzyme

我正在尝试为一个异步函数编写一个单元测试用例,该函数在内部具有for循环,并且在每次迭代中都调用Axios的“ get”方法。

我是单元测试用例的新手,我知道如何为简单的异步函数编写它,但是对于复杂的用例,我需要一些帮助。预先感谢。

export const someMethod = ({ collections }) => {
    return dispatch => {
        if (collections.length > 0) {
            for (let index = 0; index < collections.length; index++) {
                const collection = collections[index];
                const { libraryUrl, bookUrl } = collection;
                const containerId = Math.random().toString();
                dispatch(getBook({ boolURL: bookUrl, libraryURL: libraryUrl, libraryId }));
                dispatch({ 
                    type: ASSESSMENT.BOOK.ADD,
                    payload: { boolURL: bookUrl, libraryId }
                });
            }
        }
    };
};

1 个答案:

答案 0 :(得分:0)

这是解决方案:

actionCreators.ts

export const ASSESSMENT = {
  BOOK: {
    ADD: 'ADD',
    GET: 'GET'
  }
};

export const getBook = data => ({ type: ASSESSMENT.BOOK.GET, payload: { data } });

export const someMethod = ({ collections }) => {
  return dispatch => {
    if (collections.length > 0) {
      for (let index = 0; index < collections.length; index++) {
        const collection = collections[index];
        const { libraryUrl, bookUrl, libraryId } = collection;
        const containerId = Math.random().toString();
        dispatch(getBook({ boolURL: bookUrl, libraryURL: libraryUrl, libraryId }));
        dispatch({
          type: ASSESSMENT.BOOK.ADD,
          payload: { boolURL: bookUrl, libraryId }
        });
      }
    }
  };
};

actionCreators.spec.ts

import { someMethod, ASSESSMENT } from './actionCreators';
import createMockStore from 'redux-mock-store';
import thunk, { ThunkDispatch } from 'redux-thunk';
import { AnyAction } from 'redux';

const middlewares = [thunk];
const mockStore = createMockStore<any, ThunkDispatch<any, any, AnyAction>>(middlewares);

describe('someMethod', () => {
  it('t1', () => {
    const intialState = {};
    const store = mockStore(intialState);
    const collections = [
      { libraryUrl: 'aa', bookUrl: 'a', libraryId: '1' },
      { libraryUrl: 'bb', bookUrl: 'b', libraryId: '2' }
    ];
    const expectedActions = [
      {
        type: ASSESSMENT.BOOK.GET,
        payload: {
          data: {
            boolURL: collections[0].bookUrl,
            libraryURL: collections[0].libraryUrl,
            libraryId: collections[0].libraryId
          }
        }
      },
      { type: ASSESSMENT.BOOK.ADD, payload: { boolURL: collections[0].bookUrl, libraryId: collections[0].libraryId } },
      {
        type: ASSESSMENT.BOOK.GET,
        payload: {
          data: {
            boolURL: collections[1].bookUrl,
            libraryURL: collections[1].libraryUrl,
            libraryId: collections[1].libraryId
          }
        }
      },
      { type: ASSESSMENT.BOOK.ADD, payload: { boolURL: collections[1].bookUrl, libraryId: collections[1].libraryId } }
    ];
    store.dispatch(someMethod({ collections }));
    expect(store.getActions()).toEqual(expectedActions);
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/58012116/actionCreators.spec.ts
  someMethod
    ✓ t1 (6ms)

-------------------|----------|----------|----------|----------|-------------------|
File               |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-------------------|----------|----------|----------|----------|-------------------|
All files          |      100 |       50 |      100 |      100 |                   |
 actionCreators.ts |      100 |       50 |      100 |      100 |                12 |
-------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.523s

这是完整的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58012116