I am trying to test a reducer but not sure how to. the tutorials are different to how the code looks like so not sure how to implement.
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');
});
the error i receive is
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)
I have tried to follow this tutorial https://medium.com/@netxm/testing-redux-reducers-with-jest-6653abbfe3e1
In my action class the following is needed because my app goes through SSO and if the user does not have authenticated session it returns an html page
if ( typeof action.payload.data !== 'object'){
return Object.assign({}, state, {
error: {
code: "AUTHENTICATION",
message: 'Your session has expired',
action
}
});
}
UPDATE
i added actions and expected but i don't understand how this works if i am specifying the data i am meant to receive and also matching the output.
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);
});
});
If i am manually passing the action
result and then manually passing expected
how does this get tested? i understand i need to manually pass in expected
but i don't understand why i have to input the resultset into action
as well. I would have thought my action.fetchSoxApprovedCommsCount
i would have to provide the params and expect the expected
? is there any need to import actin file?
I have added minimal code here https://codesandbox.io/s/olwyjrwnjz