【发布时间】:2021-01-14 00:30:36
【问题描述】:
如何在 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();
});
});
谁能帮我说明我可能遗漏了什么或做错了什么?
【问题讨论】:
-
如果您使用 Enzyme,则应说明这一点,因为情况是特定的。见github.com/enzymejs/enzyme/issues/2086
-
@estus-flask 感谢您的链接。你的意思是坐骑还是浅层测试?我尝试将以下代码用于浅层:jest.mock('react', () => ({ ...jest.requireActual('react'), useEffect: (f) => f(), })) ;但它没有用。你介意分享一个我如何在上面的代码上实现它的例子吗?
-
只需使用 mount,shallow 还没有准备好用于功能组件。不管浅层有什么问题,你都需要等待 axios promise 在断言效果之前解决,比如
expect(axios.get).toBeCalledTimes(1); await axios.get.mock.results[0]。 -
@EstusFlask 非常感谢您的帮助!按照您的建议,我设法使用 mount 对其进行了测试。
标签: reactjs jestjs axios use-effect