我正在尝试测试一个组件,它可以渲染使用axios从unpsplash API获取的图像。然而,测试一直失败,但应用程序正在工作。
测试抛出的错误是:元素应有属性:src=”https://via.placeholder.com/300x300.png?text=robin“已收到:src=”https://via.placeholder.com/200x300/86efac?text=Loading...”
我想这一定意味着我没有正确地模拟axios请求,或者这与延迟加载有关?
我的测试:
import { screen, waitFor } from "@testing-library/react";
import { renderWithProviders } from "../utils/utils-for-tests";
import axios from "axios";
import BirdImg from "../components/BirdImg";
class IntersectionObserver {
observe() {
return null;
}
disconnect() {
return null;
}
}
window.IntersectionObserver = IntersectionObserver;
jest.mock("axios", () => ({
get: jest.fn(),
}));
const mockLoadedResponse = {
data: {
results: [
{
urls: {
thumb: "https://via.placeholder.com/300x300.png?text=robin",
},
},
],
},
};
test("shows the image", async () => {
axios.get.mockResolvedValue(mockLoadedResponse);
renderWithProviders(<BirdImg name="robin" />);
const birdImage = await screen.findByRole("img");
await waitFor(() => {
expect(birdImage).toBeInTheDocument();
expect(birdImage).toHaveAttribute(
"src",
"https://via.placeholder.com/300x300.png?text=robin"
);
});
});
我想测试的组件:
import { useEffect, useRef, useState } from "react";
import { fetchBirdImg } from "../api/unsplash";
function BirdImg({ name }) {
const imgRef = useRef(null);
const [loaded, setLoaded] = useState(false);
const [error, setError] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
fetchBirdImg(name).then((data) => {
imgRef.current.src = data[0].urls.thumb;
setLoaded(true);
});
observer.unobserve(imgRef.current);
}
});
});
observer.observe(imgRef.current);
return () => observer.disconnect();
}, [name]);
let imgSrc;
if (loaded === false) {
imgSrc = `https://via.placeholder.com/200x300/86efac?text=Loading...`;
}
if (loaded) {
imgSrc = imgRef.current.src;
}
if (error === true) {
imgSrc = `https://via.placeholder.com/200x300/86efac?text=Error`;
}
return (
<img
ref={imgRef}
onLoad={() => {
setLoaded(true);
}}
onError={() => {
setError(true);
}}
src={imgSrc}
alt={name}
className="w-20"
/>
);
}
export default BirdImg;
The api call:
import axios from "axios";
async function fetchBirdImg(name) {
const response = await axios.get(
"https://api.unsplash.com/search/photos?per_page=1&orientation=portrait",
{
headers: {
Authorization: "auth key",
},
params: { query: `${name}` },
}
);
return response.data.results;
}
export { fetchBirdImg };
1条答案
按热度按时间yfjy0ee71#
您还应该模拟
IntersectionObserver()
构造函数和unobserve()
方法您可以简单地模拟
fetchBirdImg
API函数,而不是axios
。例如:
目录结构:
BirdImg.test.jsx
:我们声明了一个
_callback
变量来保存真实的的回调函数,并在示例化IntersectionObserver
类之后用模拟的intersectionObserverEntries
对象手动调用它。测试结果: