如何使用异步try&catch操作创建器进行redux thunk单元测试?

时间:2019-04-01 04:33:42

标签: unit-testing jestjs redux-thunk fetch-mock

这是我的异步redux thunk动作创建者:

const todo = new schema.Entity('todos');
export interface FetchTodosArgs {
  page: number;
  filter: TodosFilters;
  searchText?: string;
}
export const fetchTodos = ({
  page,
  filter,
  searchText
}: FetchTodosArgs): ThunkAction<void, AppState, void, AnyAction> => async (
  dispatch,
  _getState
) => {
  dispatch({ type: FETCH_TODOS_REQUEST });
  try {
    const offset = (page - 1) * 9;
    const params: any = { offset, limit: 9, filter };
    if (searchText) {
      params.searchText = searchText;
    }
    const response = await axios.get('/api/user/todos', {
      params
    });

    const {
      result: todoIds,
      entities: { todos }
    } = normalize(
      response.data.todos.map((t: Todo) => ({
        ...t,
        id: t._id, // for normalizr
        loading: initialTodoLoadingState, // added loading specificity indicator
        errors: initialTodoErrorsState // added error specificity indicator
      })),
      [todo]
    );

    dispatch({
      type: FETCH_TODOS_SUCCESS,
      payload: { ids: todoIds, entities: todos, count: response.data.count }
    });
  } catch (error) {
    dispatch({
      type: FETCH_TODOS_FAILURE,
      payload: { error }
    });
  }
};

这是我的减速器

case FETCH_TODOS_REQUEST:
      return {
        ...state,
        loading: {
          ...state.loading,
          fetchTodos: true
        }
      };
    case FETCH_TODOS_SUCCESS:
      return {
        ...state,
        entities: {
          ...action.payload.entities
        },
        ids: [...action.payload.ids],
        count: action.payload.count,
        loading: {
          ...state.loading,
          fetchTodos: false
        }
      };
    case FETCH_TODOS_FAILURE:
      return {
        ...state,
        loading: {
          ...state.loading,
          fetchTodos: false
        },
        errors: {
          ...state.errors,
          fetchTodos: action.payload.error
        }
      };

我试图从这里的文档中复制编写测试的方式:https://redux.js.org/recipes/writing-tests#writing-tests,但我只是做不到。这是我对该动作创建者的单元测试:

describe('async actions', () => {
  afterEach(() => {
    fetchMock.restore();
  });

  it('creates FETCH_TODOS_SUCCESS when fetching todos has been done', () => {
    fetchMock
      .getOnce('/api/user/todos', {
        body: {
      todos: [
        {
          complete: true,
          createdAt: '2019-03-29T17:36:29.604Z',
          text: 'sh',
          updatedAt: '2019-03-31T19:04:52.996Z',
          userId: '5c0c0965f9c34b071c11a3f1',
          _id: '5c9e579d0b17d53cc48dbe6c'
        }
      ],
      count: 1
    },
        headers: { 'content-type': 'application/json' }
      })
      .get(
        '/api/user/todos',
        { throws: new Error('ad!') },
        { overwriteRoutes: false }
      );

    const expectedActions = [
  { type: types.FETCH_TODOS_REQUEST },
  {
    type: types.FETCH_TODOS_SUCCESS,
    payload: {
      entities: {
        '5c9e579d0b17d53cc48dbe6c': {
          complete: true,
          createdAt: '2019-03-29T17:36:29.604Z',
          text: 'sh',
          updatedAt: '2019-03-31T19:04:52.996Z',
          userId: '5c0c0965f9c34b071c11a3f1',
          _id: '5c9e579d0b17d53cc48dbe6c',
          id: '5c9e579d0b17d53cc48dbe6c',
          loading: initialTodoLoadingState,
          errors: initialTodoErrorsState
        },
        ids: ['5c9e579d0b17d53cc48dbe6c'],
        count: 1
      }
    }
  },
  {
    type: types.FETCH_TODOS_FAILURE,
    payload: { error: new Error('Network Error') }
  }
];
    const store = mockStore({ ids: [],
 entities: {}, count:0 });

    return store
      .dispatch(actions.fetchTodos({ filter: 'All', page: 1 }))
      .then(() => {
        // return of async actions
        expect(store.getActions()).toEqual(expectedActions);
      });
  });
});

我想登录store.getActions(),但是它没有登录测试?我在动作创建者和获取成功的Todos上使用normalizr,如何获取catch(错误)的模拟网络错误?

0 个答案:

没有答案