I have a component that gets form data and dispatch an action with data. This action eventually makes an ajax request to the server to send that data using javascript fetch
function.
import React, { useState, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Editor } from 'react-draft-wysiwyg';
import { EditorState } from 'draft-js';
import 'react-draft-wysiwyg/dist/react-draft-wysiwyg.css';
import { getCookie } from '../../../utils/cookies';
import { postJobAction } from './redux/postJobActions';
const PostJobComponent = () => {
const dispatch = useDispatch();
const [editorState, setEditorState] = useState(() => EditorState.createEmpty());
const [department, setDepartment] = useState('');
const postJob = (event) => { // Here is happens and I am testing this function now.
event.preventDefault();
const jobPosterId = getCookie('id');
const title = event.target.title.value;
const location = event.target.location.value;
const jobDescription = editorState.getCurrentContent().getPlainText();
dispatch(postJobAction({
jobPosterId,
title,
location,
department,
jobDescription,
}));
};
const onDepartmentChange = (event) => {
setDepartment(event.target.value);
};
return (
<div className='post-job'>
<form onSubmit={postJob}>
<div>
<label>Job Title</label>
<input
type='text'
name='title'
defaultValue=''
className='job__title'
placeholder='e.g. Frontend Developer, Project Manager etc.'
required
/>
</div>
<div>
<label>Job Location</label>
<input
type='text'
name='location'
defaultValue=''
className='job__location'
placeholder='e.g. Berlin, Germany.'
required
/>
</div>
<div>
<label>Department</label>
<select className='job__department' required onChange={onDepartmentChange}>
<option value=''>Select</option>
<option value='Customer Success'>Customer Success</option>
<option value='Professional Services'>Professional Services</option>
<option value='Service Support'>Service And Support</option>
</select>
</div>
<div style={{ border: '1px solid black', padding: '2px', minHeight: '400px' }}>
<Editor
required
editorState={editorState}
onEditorStateChange={setEditorState}
/>
</div>
<div>
<button>Save</button>
</div>
</form>
</div>
);
};
export default PostJobComponent;
Here is the test in jest and enzyme for postJob function.
it('should submit job post form on save button click', () => {
const onPostJobSubmit = jest.fn();
const instance = wrapper.instance();
wrapper.find('form').simulate('submit', {
target: {
jobPosterId: {
value: '12312jkh3kj12h3k12h321g3',
},
title: {
value: 'some value',
},
location: {
value: 'some value',
},
department: {
value: 'Customer',
},
jobDescription: {
value: 'This is Job description.',
},
},
});
expect(onPostJobSubmit).toHaveBeenCalled();
});
The code works perfectly fine but the tests are failing with below error.
expect(jest.fn()).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
98 | },
99 | });
> 100 | expect(onPostJobSubmit).toHaveBeenCalled();
| ^
101 | });
102 | });
103 |
at Object.<anonymous> (src/components/employer/jobs/postJob.test.js:100:27)
Here is the action for postJob
function that dispatches action.
export const postJobAction = (payload) => {
return {
type: 'POST_JOB_REQUEST',
payload,
}
};
Here is the saga.
import { put, call } from 'redux-saga/effects';
import { postJobService } from '../services/postJobServices';
export function* postJobSaga(payload) {
try {
const response = yield call(postJobService, payload);
yield [
put({ type: 'POST_JOB_SUCCESS', response })
];
} catch(error) {
yield put({ type: 'POST_JOB_ERROR', error });
}
}
And here is the service.
import { getCookie } from '../../../../utils/cookies';
export const postJobService = (request) => {
return fetch('http://localhost:3000/api/v1/employer/jobs', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': getCookie('token'),
},
body: JSON.stringify(request.payload)
})
.then(response => {
return response.json();
})
.then(json => {
return json;
})
.catch(error => {
return error;
});
};
Any idea how can I fix this? I am new to testing.