reactjs - 如何实现Axios和Hooks的Jest测试-useEffect

标签 reactjs jestjs axios use-effect

如何在 React 的 useEffect 中为 Axios 调用编写 Jest 测试?

我在这里找到了如何模拟 Axios - https://stackoverflow.com/a/51654713/7883067

我还知道如何触发 useEffect,如果它是由用户交互(例如单击按钮)调用的。但在以下情况下,useEffect 由 Axios 的响应触发的异步函数调用。

例子:

组件

import React, { useState, useEffect } from "react";
import axios from "axios";

const LoadImage = () => {
  const [loading, setLoading] = useState(true);
  const [data, setData] = useState(null);

  const fetchData = async () => {
    return await axios
      .get("https://picsum.photos/200/300.jpg", {
        "Content-Type": "application/xml; charset=utf-8",
      })
      .then((response) => {
        setData(response.config.url);
        setLoading(false);
      })
      .catch((error) => {
        console.log(error);
      });
  };

  useEffect(() => {
    fetchData();
  }, []);

  return (
    <div>
      {loading ? (
        <div>...loading</div>
      ) : (
        <div>
          {console.log(data)}
          <h3>Get Image</h3>
          <img alt="picsum-api" src={`${data}`} />
        </div>
      )}
    </div>
  );
};

export default LoadImage;

测试

// setUpTest.js
// import "@testing-library/jest-dom/extend-expect";
// import { configure } from "enzyme";
// import Adapter from "enzyme-adapter-react-16";
// configure({ adapter: new Adapter() });

import React from "react";
import { shallow } from "enzyme";
import * as axios from "axios";
import LoadImage from "../components/LoadImage";

describe("LoadImage test", () => {
  jest.mock("axios");
  axios.get = jest.fn();

  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<LoadImage />);
  });

  test("good response", () => {
    axios.get.mockImplementation(() => Promise.resolve({ status: 200 }));
    // expect();
  });
});

谁能帮我说明我可能遗漏了什么或做错了什么?

最佳答案

按照 Estus Flask 的建议,我设法通过使用 mount 而不是 shallow 并阅读 Robin Wieruch's post 来测试该代码。我了解如何模拟 Axios promise 。

下面是代码现在的样子:

组件

import React, { useState, useEffect } from "react";
import axios from "axios";

const LoadImage = () => {
  const [loading, setLoading] = useState(true);
  const [data, setData] = useState(null);

  const fetchData = async () => {
    return await axios.get("https://picsum.photos/200/300.jpg");
  };

  useEffect(() => {
    fetchData().then((res) => {
      setData(res.config.url);
      setLoading(false);
    });
  }, []);

  return (
    <div>
      {loading ? (
        <div>...loading</div>
      ) : (
        <div>
          <h3>Get Image</h3>
          <img alt="picsum-api" src={`${data}`} />
        </div>
      )}
    </div>
  );
};

export default LoadImage;

测试

import React from "react";
import { mount, shallow } from "enzyme";
import axios from "axios";
import { act } from "react-dom/test-utils";

import LoadImage from "../components/LoadImage";

jest.mock("axios");

// mock data
const data = {
  config: {
    url: "image-url",
  },
};

describe("LoadImage test", () => {
  let wrapper;

  // clear all mocks
  afterEach(() => {
    jest.clearAllMocks();
  });

  test("renders with loading", () => {
    wrapper = shallow(<LoadImage />);    
    expect(wrapper.find("div").first().text()).toBe("...loading");
  });

  test("loads img", async () => {

    // mock axios promise
    await act(async () => {
      await axios.get.mockImplementationOnce(() => Promise.resolve(data));
      wrapper = mount(<LoadImage />);
    });

    // check the render output
    wrapper.update();

    await expect(axios.get).toHaveBeenCalledWith("https://picsum.photos/200/300.jpg");

    await expect(axios.get).toHaveBeenCalledTimes(1);

    await expect(wrapper.find("img").props().src).toEqual("image-url");
  });
});

关于reactjs - 如何实现Axios和Hooks的Jest测试-useEffect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64101927/

相关文章:

node.js - gRPC:14 UNAVAILABLE:无法连接到所有地址

reactjs - 如何将axios返回的数据输出到屏幕

javascript - React - 使用外部 URL 时未定义 Map 函数

reactjs - Material-UI 从 DataGrid 获取所有行

javascript - 如何访问 Promise 的值?

reactjs - Formik + 是的不显示错误

javascript - 如何更改 package.json 以获得最新版本的 axios?

javascript - typescript JSDoc ...休息类型语法

reactjs - 在 React 中全局模拟 Jest/Enzyme 中的函数

javascript - 如何在超测失败时打印请求日志(如请求 url、请求正文、请求 queryParam)?