如何在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();
});
});
请问有人可以帮我看看我可能会丢失或做错什么吗?
答案 0 :(得分:3)
根据Estus Flask的建议,我设法通过使用mount而不是浅表来测试该代码,并阅读了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");
});
});