首页 > 解决方案 > 尝试测试使用 Jest 进行 axios 调用的组件时获取“_axios.default.create is not a function”

问题描述

我正在尝试使用 Jest/Enzyme 来测试 axios 函数是否通过。我尝试了各种解决方案、模拟方式,以及重新设计组件本身以让测试识别 axios 请求,但我一直收到同样的错误。

在这一点上,我已经修改了我的测试以通过 axios 失败,然后我将返回到有条件的通过/失败测试。现在我的测试很明显:

import { shallow }  from 'enzyme';
import Assets from '../src/components/App';

jest.mock('axios', () => {
  return {
    __esModule: true,
    default: jest.fn()
  }
});

describe("Component", () => {
  const component = shallow(<App />);    
})

我得到了返回错误:

TypeError: _axios.default.create is not a function

该应用程序的问题引用了来自 App.js 上另一个文件的 axios 请求,有一个命令:

let response = await axiosGetTest.get('...');

axiosGetTest 是另一个文件中的函数,错误源自该文件,在该文件中我们有:

const axiosGetTest = axios.create({
    baseURL: '...',
    timeout: 15000,
    headers: {
     ...
    }
});

抱歉,如果解释很粗略,我对 JavaScript 中的单元测试很陌生

标签: reactjsunit-testingjestjsaxiosenzyme

解决方案


这是一个单元测试示例:

App.jsx

import React, { Component } from 'react';
import axios from 'axios';

const axiosGetTest = axios.create({
  baseURL: 'http://localhost:3000',
  timeout: 15000,
  headers: {},
});

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = { user: { name: '' } };
  }
  componentDidMount() {
    axiosGetTest.get('/api/user').then((user) => this.setState({ user }));
  }
  render() {
    const { user } = this.state;
    return <div>{user.name}</div>;
  }
}

App.test.jsx

import { shallow } from 'enzyme';
import axios from 'axios';
import App from './App';
import { act } from 'react-dom/test-utils';

async function flushEffects() {
  await act(async () => {
    await new Promise((resolve) => setTimeout(resolve, 0));
  });
}

jest.mock('axios', () => {
  const mAxiosInstance = { get: jest.fn() };
  return {
    create: jest.fn(() => mAxiosInstance),
  };
});

describe('66465749', () => {
  afterAll(() => {
    jest.resetAllMocks();
  });
  it('should pass', async () => {
    axios.create().get.mockResolvedValueOnce({ name: 'teresa teng' });
    const wrapper = shallow(<App></App>);
    expect(wrapper.state('user')).toEqual({ name: '' });
    await flushEffects();
    expect(wrapper.state('user')).toEqual({ name: 'teresa teng' });
  });
});

单元测试结果:

 PASS  examples/66465749/App.test.jsx
  66465749
    ✓ should pass (16 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 App.jsx  |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.68 s, estimated 4 s

源代码:https ://github.com/mrdulin/jest-v26-codelab/tree/main/examples/66465749


推荐阅读