【问题标题】:How to mock API calls made with Axios?如何模拟使用 Axios 进行的 API 调用?
【发布时间】:2021-07-11 07:37:21
【问题描述】:

我有一个名为 Home.jsx 的组件,它借助 axios 实例在 useEffect 中进行异步调用。现在,在 Home.test.jsx 中为 Home 编写测试时,我遇到了这个 API 调用的问题,因为 API 调用需要授权,并且测试是在终端而不是浏览器中运行的。如果我使用findBywaitFor,那么API 调用应该会失败,因为没有发生授权。我正在使用axios.create({}) 实例,没有其他问题对我有帮助。

//Home.jsx
import services from "../../Services/patientServices";

const Home = () => {
  const [patientSets, setPatientSets] = useState([]);

  const fetchPatientSets = async () => {
    try {
      const result = await services.patientSets();
      console.log('Data => ', result);
      setPatientSets(result.data);
    }
    catch(err) {
      setPatientFetching(false);
    }
  }

  useEffect(() => {
    fetchPatientSets();
  }, []);
}
//Services.js
import apiClient from "./apiClient";

const patientSets = async () => {
  return await apiClient().get(`patient_sets`);
};
//ApiClient.js
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;
}
//Home.test.jsx
import React from 'react';
import { render, screen } from '../../setupTests';
import Home from './Home';

describe('Home', () => {
  test('Test refresh button in the table', async () => {
    const { container } = render(<Home />);
    expect(await screen.findBy('async data').toBeInTheDocument();
  });
});

【问题讨论】:

  • 您不需要模拟 Axios 来进行单元测试 Home,只需 patientSets。您也可以使用 MSW 之类的东西,请参阅我写的示例 here。但到目前为止,您似乎还没有尝试模拟 任何东西

标签: reactjs unit-testing jestjs react-testing-library


【解决方案1】:

Home 组件直接依赖于patientServices 模块。为了使单元尽可能小,您应该模拟patientServices 而不是axios

单位越大,测试越复杂。

例如

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

测试结果:

 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-15
    • 2018-02-21
    • 1970-01-01
    • 2020-11-06
    • 2017-12-22
    • 2017-08-31
    • 2020-12-15
    • 2021-11-10
    相关资源
    最近更新 更多