简体   繁体   中英

How to Test a Reactcomponent which has Axios call in componentDidMount using JEST with ENZYME?

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));
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM