The Home component directly depends on the patientServices module. In order to make the unit as small as possible, you should mock patientServices instead of axios.
The larger the unit, the more complex the test.
E.g.
Home.jsx:
import services from './services/patientServices';
import React, { useState, useEffect } from 'react';
export const Home = () => {
const [patientSets, setPatientSets] = useState([]);
const fetchPatientSets = async () => {
try {
const result = await services.patientSets();
console.log('Data => ', result);
setPatientSets(result.data);
} catch (err) {}
};
useEffect(() => {
fetchPatientSets();
}, []);
return (
<div>
<ul>
{patientSets.map((p) => {
return <li key={p.id}>{p.name}</li>;
})}
</ul>
</div>
);
};
apiClient.js
import axios from 'axios';
const apiClient = () => {
const access_token = localStorage.getItem('access_token');
const instance = axios.create({
baseURL: window.config.apiUrl,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${access_token}`,
},
responseType: 'json',
});
return instance;
};
export default apiClient;
services/patientServices.js:
import apiClient from '../apiClient';
const patientSets = async () => {
return await apiClient().get(`patient_sets`);
};
export default { patientSets };
Home.test.jsx:
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { Home } from './Home';
import services from './services/patientServices';
jest.mock('./services/patientServices');
describe('67122477', () => {
afterAll(() => {
jest.resetAllMocks();
});
it('should pass', async () => {
const mResult = { data: [{ name: 'teresa teng', id: '1' }] };
services.patientSets.mockResolvedValueOnce(mResult);
render(<Home />);
const matched = await screen.findByText(/teresa teng/);
expect(matched).toBeInTheDocument();
});
});
test result:
PASS examples/67122477/Home.test.jsx (11.771 s)
67122477
✓ should pass (45 ms)
console.log
Data => { data: [ { name: 'teresa teng', id: '1' } ] }
at examples/67122477/Home.jsx:10:15
---------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
---------------------|---------|----------|---------|---------|-------------------
All files | 80.77 | 100 | 62.5 | 82.61 |
67122477 | 85.71 | 100 | 83.33 | 84.21 |
Home.jsx | 100 | 100 | 100 | 100 |
apiClient.js | 50 | 100 | 0 | 50 | 4-13
67122477/services | 60 | 100 | 0 | 75 |
patientServices.js | 60 | 100 | 0 | 75 | 4
---------------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 14.449 s
Answer from Lin Du on Stack Overflowreactjs - How to test axios api using jest and react testing library? - Stack Overflow
reactjs - How to mock axios in React with using axios.create function - Stack Overflow
The best approach to have a mock API in ReactJS and toggle between the real API calls and the fake one?
Is there a way to test API endpoints in React without mocking the requests?
Videos
» npm install axios-mock-adapter
You must mock axios and look if axios methods are called with the right parameters for example.
apis.spec.js
import apis from './apis';
jest.mock('axios'); // This overwrites axios methods with jest Mock
import axios from 'axios';
describe('Test Apis', () => {
describe('getResource', () => {
describe('with success', () => {
const url = 'http://test-url.com';
const onComplete = jest.fn();
const data = {};
beforeEach(() => {
axios.get.mockResolvedValue(data);
});
it('should call axios get with given url', () => {
getResource(url, onComplete);
expect(axios.get).toBeCalledWith(url);
});
it('should call onComplete callback with response', async () => { // do not forget 'async'
await getResource(url, onComplete); // notice the 'await' because onComplete callback is called in '.then'
expect(onComplete).toBeCalledWith(data);
});
});
});
});
You could do the same with the error response and POST method. You could also test your LookingGlassAPIs by mocking your apis.js methods, or again by mocking axios, it depends of your "unit" definition inside your project.
As long as the functions you want to test don't return anything, you could test if they throw or no.
You would need to spy your axios methods, mocking a return value (in this case a Promise), something like:
import axios from 'axios';
beforeAll(() => {
axios.get.mockImplementation(() => Promise.resolve('whatever-get'));
axios.post.mockImplementation(() => Promise.resolve('whatever-post'));
});
afterAll(() => {
jest.clearAllMocks();
});
test('get does not throw', () => {
expect(getResource()).not.toThrow();
});
test('post does not throw', () => {
expect(postResource()).not.toThrow();
});
» npm install jest-mock-axios