【问题标题】:How to Test a Reactcomponent which has Axios call in componentDidMount using JEST with ENZYME?如何使用 JEST 和 ENZYME 测试在 componentDidMount 中调用 Axios 的 React 组件?
【发布时间】:2021-04-14 18:51:01
【问题描述】:

简介 我想测试一个在 componentDidMount 中有 axios 调用的组件。我已经尝试了所有方法,但每次我都遇到与 axios 相同的问题。

错误:

  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)

技术栈 - 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 - 第一个 TestCase 简单渲染也无法正常工作,面临与上述相同的错误。

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

总结:

测试工作正常没有 axios 和它测试用例。如果我调用 axios,所有与 axios 无关的测试用例 (简单浅渲染) 也会失败。

【问题讨论】:

  • 对于像.loadUsers 这样的实现细节,我并不是很着迷。 12 可能会有所帮助。副手,我认为你需要mount 而不是shallow
  • @ggorlen 我已按照 1 和 2 中指定的步骤进行操作,但我仍然面临与顶部指定的相同错误。如果我运行测试用例,实际组件 会导致错误。并且相同的组件 在浏览器中运行良好。测试用例失败 axios.get('jsonplaceholder.typicode.com/todos/1')

标签: reactjs jestjs enzyme jest-mock-axios


【解决方案1】:

试试axios-mock-adapter

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

【讨论】:

    猜你喜欢
    • 2018-08-20
    • 2021-06-24
    • 2021-09-16
    • 2017-04-13
    • 2022-01-18
    • 2021-08-29
    • 2018-08-31
    • 2017-02-12
    • 2018-12-23
    相关资源
    最近更新 更多