I’m building a React component which, when mounted, gets data from the server via AJAX.
I’m trying (and failing) to mock the AJAX call in Jest and am wondering if I’m just misunderstanding how mocking in Jest really works?
My file structure is:
- index.js
- index.test.js
- requests.js
- __mocks__
- requests.js
The component (index.js) makes the call via requests.js, which uses Axios to get data from the server. requests.js is mocked inside the __mocks__ folder.
As can be seen below in the test file index.test.js, I’m using getSpy to detect if the requests.getData function is called. It never is. I should add that I’ve also tried to get the component to simply render some of the data from the getData function response, and then, in the test file, run console.log(ListWrapper.debug()); to see whether the data is rendered in the test. Again, it never is.
Just wondering if anyone can spot where I’m going wrong, or if I’m just getting the wrong end of the stick?
index.test.js
import React from 'react';
import { mount } from 'enzyme';
import List from './index';
import expect from 'expect';
import requests from './requests';
jest.mock('requests');
describe('Renders list', () => {
const getSpy = jest.spyOn(requests, 'getData');
const ListWrapper = mount(
<ListWrapper />
);
console.log(ListWrapper.debug());
it('should fetch currencies', () => {
expect(getSpy).toBeCalled();
});
});
__mocks__/requests.js
module.exports = {
getData: () => {
return new Promise((resolve) => {
resolve({
[
{
id: 1,
name: 'Bob Smith',
age: 32
}
]
});
});
}
};
index.js (shortened)
/**
* List component
*/
import React, { useState, useEffect, useCallback } from 'react';
import * as requests from './requests’;
function List(props) {
const [data, setData] = useState([]);
/**
* Get data from server
*/
const getCurrencies = useCallback(() => {
r4_uiTools.loadingAnimation.show();
requests
.getData()
.then((response) => {
setData(response);
})
.catch(error) {
//...
}
/**
* Get data when first mounting component
*/
useEffect(() => {
getData();
}, [getData]);
return(
<>
/* ... */
{data[0].name}
</>
);
requests.js (shortened)
import axios from 'axios';
const getData = () => {
return new Promise((resolve, reject) => {
const url = `/MyURL/`;
axios
.get(url)
.then((response) => {
resolve(response);
})
.catch((error) => {
reject(error);
});
});
};
export { getData };