如何在使用 Jest 和 redux 操作时匹配返回的 Promise
how to match a returned Promise in using Jest with redux action
我正在将 reactjs 与 redux 结合使用,并且操作是使用 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",
},
]
actions/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);
});
});
我添加了 promise 作为中间件
结果
(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
成为未解决的承诺。
解决此问题的一种方法是使用 async/await 方法:
export async function fetchContentVideoList(page, size, where, sort) {
const request = await axios.get('url');
return {
type: FETCH_CONTENT_VIDEO_LIST,
payload: request
};
}
有关详细信息,请参阅 async docs on MDN。
编辑问题更新
此更改将操作变成异步操作,这意味着需要以稍微不同的方式处理它。在 promise 解决后做出期望(就像你正在做的那样)是测试操作的一种好方法。
我正在将 reactjs 与 redux 结合使用,并且操作是使用 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",
},
]
actions/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);
});
});
我添加了 promise 作为中间件
结果
(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
成为未解决的承诺。
解决此问题的一种方法是使用 async/await 方法:
export async function fetchContentVideoList(page, size, where, sort) {
const request = await axios.get('url');
return {
type: FETCH_CONTENT_VIDEO_LIST,
payload: request
};
}
有关详细信息,请参阅 async docs on MDN。
编辑问题更新
此更改将操作变成异步操作,这意味着需要以稍微不同的方式处理它。在 promise 解决后做出期望(就像你正在做的那样)是测试操作的一种好方法。