我在redux中使用reactjs,操作是在使用axios并返回Promise。我的测试与类型不匹配。我尝试了不同的方法,但是最终遇到了同样的问题。还尝试了https://www.leighhalliday.com/mocking- axios-in-jest-testing-async-functions
import configureMockStore from 'redux-mock-store' //import fetchMock from 'fetch-mock' import expect from 'expect' // You can use any testing library import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import * as actions from '../../../app/actions/admin' import * as types from '../../../app/reducers/reducer_content' //const middlewares = [thunk] const mockStore = configureMockStore() descri be('async actions', () => { it('FETCH_CONTENT_VIDEO_LIST', () => { let mock = new MockAdapter(axios); const data = { response: true }; mock.onGet('/contentvideolist').reply(200, data); console.log(types); const expectedActions = [{"payload": {}, "type": actions.FETCH_CONTENT_VIDEO_LIST}] const store = mockStore({ fetch_content_video_list: [] }) console.log(actions); store.dispatch(actions.fetchContentVideoList()); expect(store.getActions()).toEqual(expectedActions); }); });
这是结果
expect(received).toEqual(expected) Expected value to equal: [{"payload": {}, "type": "fetch_content_video_list"}] Received: [{"payload": {}, "type": "fetch_content_video_list"}] Difference: - Expected + Received Array [ Object { - "payload": Object {}, + "payload": Promise {}, "type": "fetch_content_video_list", }, ]
动作/admin.js
export const FETCH_CONTENT_VIDEO_LIST = 'fetch_content_video_list'; export function fetchContentVideoList(page, size, where, sort) { const request = axios.get(`/api/user/get/content/management/method/video/list/format/json?quiet=1&page=` + page + `&size=` + size + `&where=` + JSON.stringify(where) + `&sort=` + sort); return { type: FETCH_CONTENT_VIDEO_LIST, payload: request }; }
更新后出现新错误
Actions must be plain objects. Use custom middleware for async actions. 23 | const store = mockStore({ fetch_content_video_list: [] }) 24 | console.log(actions); > 25 | store.dispatch(actions.fetchContentVideoList()); 26 | expect(store.getActions()).toEqual(expectedActions); 27 | }); 28 | });
更新
import configureMockStore from 'redux-mock-store' import promise from 'redux-promise'; import expect from 'expect' // You can use any testing library import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import * as actions from '../../../app/actions/admin' import * as types from '../../../app/reducers/reducer_content' const middlewares = [promise] const mockStore = configureMockStore(middlewares) describe('async actions', () => { it('FETCH_CONTENT_VIDEO_LIST', () => { let mock = new MockAdapter(axios); const data = { response: true }; mock.onGet('/contentvideolist').reply(200, data); console.log(types); const expectedActions = [{"payload": {}, "type": actions.FETCH_CONTENT_VIDEO_LIST}] const store = mockStore({ fetch_content_video_list: [] }) console.log(actions); store.dispatch(actions.fetchContentVideoList()); expect(store.getActions()).toEqual(expectedActions); }); });
我添加了诺言作为中间件
结果
(node:19685) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): Error: Request failed with status code 404 (node:19685) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. FAIL tests/jest/actions/admin.test.js async actions ✕ FETCH_CONTENT_VIDEO_LIST (43ms) ● async actions › FETCH_CONTENT_VIDEO_LIST expect(received).toEqual(expected) Expected value to equal: [{"payload": {}, "type": "fetch_content_video_list"}] Received: [] Difference: - Expected + Received - Array [ - Object { - "payload": Object {}, - "type": "fetch_content_video_list", - }, - ] + Array [] 24 | console.log(actions); 25 | store.dispatch(actions.fetchContentVideoList()); > 26 | expect(store.getActions()).toEqual(expectedActions); 27 | }); 28 | }); 29 | at Object.<anonymous> (tests/jest/actions/admin.test.js:26:32) console.log tests/jest/actions/admin.test.js:21 { default: [Function] } console.log tests/jest/actions/admin.test.js:24 { FETCH_CONTENT_VIDEO_LIST: 'fetch_content_video_list', fetchContentVideoList: [Function: fetchContentVideoList], FETCH_CONTENT_VIDEO_LIST_COUNT: 'fetch_content_video_list_count', UPDATE_CONTENT_VIDEO_LIST: 'update_content_video_list', fetchContentVideoListCount: [Function: fetchContentVideoListCount], updateContentVideoList: [Function: updateContentVideoList] }
固定
添加了then子句。这是正确的方法吗?
import configureMockStore from 'redux-mock-store' import promise from 'redux-promise'; import expect from 'expect' // You can use any testing library import axios from 'axios'; import * as actions from '../../../app/actions/admin' const middlewares = [promise] const mockStore = configureMockStore(middlewares) const store = mockStore({ }) beforeEach(() => { // Runs before each test in the suite store.clearActions(); }); describe('async actions', () => { it('FETCH_CONTENT_VIDEO_LIST', () => { const expectedActions = [{"payload": {}, "type": actions.FETCH_CONTENT_VIDEO_LIST}] store.dispatch(actions.fetchContentVideoList()).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); it('FETCH_CONTENT_VIDEO_LIST_COUNT', () => { const expectedActions = [{"payload": {}, "type": actions.FETCH_CONTENT_VIDEO_LIST_COUNT}] store.dispatch(actions.fetchContentVideoListCount()).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); it('UPDATE_CONTENT_VIDEO_LIST', () => { const expectedActions = [{"payload": {}, "type": actions.UPDATE_CONTENT_VIDEO_LIST}] store.dispatch(actions.updateContentVideoList()).then(() => { expect(store.getActions()).toEqual(expectedActions); }); }); });
fetchContentVideoList不等待诺言被解决或拒绝,所以payload成为未解决的诺言。
fetchContentVideoList
payload
解决此问题的一种方法是使用async / await方法:
export async function fetchContentVideoList(page, size, where, sort) { const request = await axios.get('url'); return { type: FETCH_CONTENT_VIDEO_LIST, payload: request }; }
有关更多信息,请参见MDN上的异步文档。
编辑问题更新
此更改将操作转变为异步操作,这意味着需要以稍微不同的方式来处理它。在诺言解决之后(如您所做的那样)做出期望是测试行动的一种好方法。