这是我的异步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(错误)的模拟网络错误?