[英]Testing react component with jest
我正在關注關於反應的測試文檔,數據獲取部分: https : //reactjs.org/docs/testing-recipes.html#data-fetching
它使用 fetch 來獲取數據。 我用 axios 嘗試過同樣的方法,但出現以下錯誤:
TypeError: Cannot read property 'textContent' of null
> 43 | expect(container.querySelector(".uid").textContent).toBe(fakeUser.userId);
| ^
44 | expect(container.querySelector(".id").textContent).toBe(fakeUser.id);
45 | expect(container.querySelector(".title").textContent).toBe(fakeUser.title);
我認為錯誤是因為 jest 沒有等待 axios 獲取數據然后重新渲染組件。 我不知道等待元素。
這是 User.js
import React from "react";
import axios from "axios";
class User extends React.Component {
state = {
user: null
};
componentDidMount() {
this.fetchUserData("1");
}
async fetchUserData(id) {
const response = await axios.get(
`https://jsonplaceholder.typicode.com/albums/${id}`
);
const user = await response.data;
this.setState({
user
});
}
render() {
const { user } = this.state;
if (!user) {
return <div>loading...</div>;
}
return (
<div>
<div className="uid">{user.userId}</div>
<div className="id">{user.id}</div>
<div className="title">{user.title}</div>
</div>
);
}
}
export default User;
這是 User.test.js
import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import User from "./User";
import axios from "axios";
let container = null;
jest.mock("axios");
beforeEach(() => {
// setup a DOM element as a render target
container = document.createElement("div");
document.body.appendChild(container);
});
afterEach(() => {
// cleanup on exiting
unmountComponentAtNode(container);
container.remove();
container = null;
});
it("renders user data", async () => {
const fakeUser = {
userId: "1",
id: "1",
title: "quidem molestiae enim"
};
axios.get.mockResolvedValue(fakeUser);
// Use the asynchronous version of act to apply resolved promises
await act(async () => {
render(<User id="1" />, container);
});
expect(container.querySelector(".uid").textContent).toBe(fakeUser.userId);
expect(container.querySelector(".id").textContent).toBe(fakeUser.id);
expect(container.querySelector(".title").textContent).toBe(fakeUser.title);
});
嗯,我解決了這個問題。 解決方案是模擬axios
並使用mockImplementation
模擬實現響應
import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import User from "./User";
import axios from "axios";
let container = null;
jest.mock("axios");
beforeEach(() => {
// setup a DOM element as a render target
container = document.createElement("div");
document.body.appendChild(container);
});
afterEach(() => {
// cleanup on exiting
unmountComponentAtNode(container);
container.remove();
container = null;
});
it("renders user data", async () => {
const fakeUser = {
userId: "1",
id: "1",
title: "quidem molestiae enim"
};
axios.get.mockImplementation(() =>
Promise.resolve({
data: fakeUser
})
);
// Use the asynchronous version of act to apply resolved promises
await act(async () => {
render(<User id="1" />, container);
});
expect(container.querySelector(".uid").textContent).toBe(fakeUser.userId);
expect(container.querySelector(".id").textContent).toBe(fakeUser.id);
expect(container.querySelector(".title").textContent).toBe(fakeUser.title);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.