Introduction I want to test a component that has axios call in componentDidMount. I have tried all the ways but ever time I'm facing the same issue with axios.
Error:
axios.get('https://jsonplaceholder.typicode.com/todos/1')
| ^
at Welcome.loadUsers (src/Testing/welcome.js:23:9)
at Welcome.componentDidMount (src/Testing/welcome.js:19:14)
at fn (node_modules/enzyme/src/ShallowWrapper.js:429:22)
at Object.batchedUpdates (node_modules/enzyme-adapter-react-16/src/ReactSixteenAdapter.js:781:16)
at new ShallowWrapper (node_modules/enzyme/src/ShallowWrapper.js:428:26)
at shallow (node_modules/enzyme/src/shallow.js:10:10)
at Object.<anonymous> (tests/welcome.test.js:11:15)
Techonlogy Stack - Package.json:
"axios": "^0.21.1",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"jest": "^26.6.3",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5",
"enzyme-to-json": "^3.6.1",
Welcome.js
import React, { Component } from 'react';
import {loadUsers} from './api';
class Welcome extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
user: null,
error: false,
errMsg: ''
}
}
componentDidMount(){
this.setState({
isLoading: true
});
this.loadUsers();
}
loadUsers=()=>{
axios.get('https://jsonplaceholder.typicode.com/todos/1')
.then(resp=>{
this.setState({
isLoading: false,
user: resp.data,
error: false,
errMsg: ''
});
})
.catch(exep =>{
this.setState({
isLoading: false,
user: null,
error: true,
errMsg: exep.message
});
});
}
render() {
const {isLoading, user, error, errMsg} = this.state;
return (
<React.Fragment>
<h2 className='helloWorld'>Hello World</h2>
{
isLoading ? <h3 className='loader'>Loading...</h3> :
user != null ? <h2>Welcome {user.title}</h2> :
error ? <h3>{errMsg}</h3> : <h4>No Data Found</h4>
}
</React.Fragment>
)
}
}
export default Welcome;
Welcome.Tests.js - 1st TestCase Simple Rendering is also not working facing the same error as stated above.
import React from 'react';
import axios from 'axios';
import { shallow, mount } from 'enzyme';
import Welcome from '../src/Testing/welcome';
import toJson from 'enzyme-to-json';
jest.mock('axios');
let wrapper;
beforeEach(()=>{
wrapper = shallow(<Welcome/>);
});
describe('<Welcome/>:: Rendering', ()=>{
it('should load hello world', ()=>{
except(wrapper.find(‘h2.helloworld’).text()).toEquals(‘Hello World’)
});
describe('<Welcome/>:: Mocking', ()=>{
it('should fetch users', ()=>{
const user = {
userId: 1,
id: 1,
title: "test",
completed: false
};
axios.get.mockResolvedValue(user);
const instance = wrapper.instance();
return instance.loadUsers().then(data=> expect(data).toBe(user));
});
});
describe('<Welcome/>:: Trigger Life Cycle',()=>{
it('should check for componentDidMount',()=>{
shallow(<Welcome/>).debug();
const instance = wrapper.instance();
jest.spyOn(instance, 'loadUsers');
instance.componentDidMount();
expect(instance.loadUsers).toHaveBeenCalledTimes(1);
});
});
Summary:
Test are Working fine without axios and it test cases. And If I place axios call, all testcase which are not even related to axios (simple shallow rendering) are also failed.
Give axios-mock-adapter
a try:
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
describe('<Welcome/>:: Mocking', ()=>{
it('should fetch users', ()=>{
const user = {
userId: 1,
id: 1,
title: "test",
completed: false
};
const mock = new MockAdapter(axios);
mock.onGet().reply(200, user);
const instance = wrapper.instance();
return instance.loadUsers().then(data=> expect(data).toBe(user));
});
});