我正在尝试测试减速器,但不确定如何进行。这些教程与代码的外观不同,因此不确定如何实现。
actions / audit.js
import axios from 'axios';
export const FETCH_SOX_APPROVED_COMMS = 'fetch_sox_approved_comms';
export async function fetchSoxApprovedComms(page, size, where, sort) {
const request = await axios.get(`/api/user/report/sox/approved/comms/format/json?quiet=1&page=` + page + `&size=` + size + `&where=` + JSON.stringify(where) + `&sort=` + sort);
return {
type: FETCH_SOX_APPROVED_COMMS,
payload: request
};
}
export const FETCH_SOX_APPROVED_COMMS_COUNT = 'fetch_sox_approved_comms_count';
export async function fetchSoxApprovedCommsCount(where) {
const request = await axios.get(`/api/user/report/sox/approved/comms/count/format/json?quiet=1&where=` + JSON.stringify(where));
return {
type: F
ETCH_SOX_APPROVED_COMMS_COUNT,
payload: request
};
}
reducers / reducer_audit.js
import {
FETCH_SOX_APPROVED_COMMS,
FETCH_SOX_APPROVED_COMMS_COUNT
} from '../actions/audit';
export default function(state = {}, action) {
switch (action.type) {
case FETCH_SOX_APPROVED_COMMS:
case FETCH_SOX_APPROVED_COMMS_COUNT:
if ( typeof action.payload.data !== 'object'){
return Object.assign({}, state, {
error: {
code: "AUTHENTICATION",
message: 'Your session has expired',
action
}
});
}else if (action.payload.data.header.error) {
return Object.assign({}, state, {
error: {
code: "INVALID ACTION",
message: action.payload.data.header.message,
action
}
});
} else {
return action.payload.data.body.recordset.record;
}
default:
return state;
}
}
tests / jest / reducers / reducer_audit.test.js
import reducer from '../../../app/reducers/reducer_audit';
import * as actions from '../../../app/actions/audit';
import expect from 'expect';
describe('audit reducer', () => {
it('should return the initial state', () => {
expect(reducer(undefined, {})).toEqual({});
});
it('should handle FETCH_SOX_APPROVED_COMMS_COUNT', () => {
const expected = {
type: actions.FETCH_SOX_APPROVED_COMMS_COUNT
};
// it's empty on purpose because it's just starting to fetch posts
expect(reducer({}, expected)).toEqual({});
});
it('should handle FETCH_SOX_APPROVED_COMMS');
});
我收到的错误是
audit reducer
✓ should return the initial state (2ms)
✕ should handle FETCH_SOX_APPROVED_COMMS_COUNT (7ms)
○ skipped 1 test
● audit reducer › should handle FETCH_SOX_APPROVED_COMMS_COUNT
TypeError: Cannot read property 'data' of undefined
8 | case FETCH_SOX_APPROVED_COMMS:
9 | case FETCH_SOX_APPROVED_COMMS_COUNT:
> 10 | if ( typeof action.payload.data !== 'object'){
11 | return Object.assign({}, state, {
12 | error: {
13 | code: "AUTHENTICATION",
at Object.<anonymous>.exports.default (app/reducers/reducer_audit.js:10:30)
at Object.<anonymous> (tests/jest/reducer/reducer_audit.test.js:15:9)
我已尝试遵循本教程https://medium.com/@netxm/testing-redux-reducers-with-jest-6653abbfe3e1
在我的动作类中,需要执行以下操作,因为我的应用通过SSO,并且如果用户没有经过身份验证的会话,它将返回一个html页面
if ( typeof action.payload.data !== 'object'){
return Object.assign({}, state, {
error: {
code: "AUTHENTICATION",
message: 'Your session has expired',
action
}
});
}
更新
我添加了一些预期的动作,但是如果我指定要接收的数据并匹配输出,我将无法理解它的工作原理。
import reducer from '../../../app/reducers/reducer_audit';
import * as actions from '../../../app/actions/audit';
import expect from 'expect';
describe('audit reducer', () => {
it('should return the initial state', () => {
expect(reducer(undefined, {})).toEqual({});
});
it('should handle FETCH_SOX_APPROVED_COMMS_COUNT', () => {
const expected = {
id: 1,
name: 'testname'
};
let action = {
type: actions.FETCH_SOX_APPROVED_COMMS_COUNT,
payload: {
data: {
header: {
error: null
},
body: {
recordset: {
record: {
id: 1,
name: 'testname'
}
}
}
}
}
}
expect(reducer({}, action)).toEqual(expected);
});
it('should handle FETCH_SOX_APPROVED_COMMS', () => {
const expected = {
'approver_email':'',
'id':1,
'sox_approved':'',
'sox_submission':'',
'submitted_by':''
};
let action = {
type: actions.FETCH_SOX_APPROVED_COMMS,
payload: {
data: {
header: {
error: null
},
body: {
recordset: {
record: {
'approver_email':'',
'id':1,
'sox_approved':'',
'sox_submission':'',
'submitted_by':''
}
}
}
}
}
}
expect(reducer({}, action)).toEqual(expected);
});
});
如果我手动通过action
结果,然后手动通过expected
,该如何测试?我知道我需要手动传递expected
,但是我不明白为什么我也必须将结果集输入action
中。我本以为我的action.fetchSoxApprovedCommsCount
必须提供参数并期望expected
?是否需要导入肌动蛋白文件?
答案 0 :(得分:1)
收到错误消息是因为忘记了在测试操作中包含有效载荷。
您要将以下操作传递给减速器。
{
type: actions.FETCH_SOX_APPROVED_COMMS_COUNT
}
Reducer尝试读取action.payload.data
,这会导致错误,因为action.payload
是undefined
。
您必须传递带有一些实际数据的动作。例如:
const action = {
type: actions.FETCH_SOX_APPROVED_COMMS_COUNT,
payload: {
data: {
header: {
error: null
},
body: {
recordset: {
record: {
id: 1,
name: 'testname'
}
}
}
}
}
}
之后,您应该expect
适当的值。在我的例子中
expect(reducer({}, action)).toEqual({ id: 1, name: 'testname' })
会通过。