如何使用 react 测试库单击父组件上的按钮后测试子组件渲染文本?



我有一个父组件App它有一个按钮。单击按钮时,它将调用axios以获取帖子,然后呈现帖子项目。App有一个子组件PostPost有一个子组件ListItem。在我的应用程序测试文件中,我已经测试了 axios 可以在单击按钮后正确加载。但是,我无法测试渲染的内容。它找不到data-testidUnable to find an element by: [data-testid="test-axios-content"]

我使用react testing library.

这是我的测试文件:

import React from "react"
import App from "../../App"
import { render, fireEvent, screen, waitFor, act } from "../utils/test-utils"
import axios from "axios"
jest.mock("axios", () => {
return {
get: jest.fn()
}
})
describe("App test", () => {
afterEach(() => {
jest.resetAllMocks()
})
it("should load and display the data", async () => {
const { getByTestId } = render(<App />)
axios.get.mockResolvedValueOnce({
data: { title: "hello there", body: "abc" }
})
await act(async () => {
fireEvent.click(getByTestId("test-axios-button"))
expect(axios.get).toHaveBeenCalledTimes(1)
const testingData = await waitFor(() => getByTestId("test-axios-content"))
expect(testingData).toHaveTextContent("hello there")
})
})
})

第一个 axios 调用时间是正确的,但我的测试找不到 testIdtest-axios-content。我把它放在应用程序.js上的子组件上。

应用.js

...
function App() {
const [posts, setPosts] = useState([])
const handleClick= async () => {
const postsResult = await getPosts()
setPosts(postsResult.data)
}
return (
<div className="App" data-test="appComponent">
<button data-testid="test-axios-button" onClick={handleClick}>
get post from axios
</button>
<section>
<div>Load Posts:</div>
<Post posts={posts} data-testid="test-axios-content" />
</section>
</div>
}
...

API getPosts:

import axios from "axios"
export const getPosts = async () => await axios.get("https://jsonplaceholder.typicode.com/posts?_limit=10")

发布:

import ListItem from "../listItem"
const Post= (props) => {
const posts = props.posts
return (
<>
{posts.length > 0 && (
<div>
{posts.map((post, index) => {
const { title, body } = post
return <ListItem key={title} title={title} desc={body} />
})}
</div>
)}
</>
)
}
export default Post

列表项:

const ListItem = (props) => {
const { title, desc } = props
return (
<div>
<h2 data-test="title" data-testid="title">
{title}
</h2>
<div data-test="desc" data-testid="desc">
{desc}
</div>
</div>
)
}
export default ListItem

第一个错误的部分是posts是一个数组,但在axios mock上,它是一个对象:{ title: "hello there", body: "abc" }。正确的格式是:[{ title: "hello there", body: "abc" }]

因此,在测试axios mock部分,正确的代码是:

axios.get.mockResolvedValueOnce({
data: [{ title: "hello there", body: "abc" }]
})

第二个错误的部分是,与其使用await act,不如先使用触发器单击,然后再使用带有回调的await waitFor

fireEvent.click(getByTestId("test-axios-button"))
await waitFor(() => {
expect(axios.get).toHaveBeenCalledTimes(1)
const renderData = screen.getByText("hello there")
expect(renderData).toBeInTheDocument()
})

这是决赛:

it("should load and display the data", async () => {
const { getByTestId } = render(<App />)
axios.get.mockResolvedValueOnce({
data: [{ title: "hello there", body: "abc" }]
})
fireEvent.click(getByTestId("test-axios-button"))
await waitFor(() => {
expect(axios.get).toHaveBeenCalledTimes(1)
const testingData = await waitFor(() => getByTestId("test-axios-content"))
expect(testingData).toHaveTextContent("hello there")
})
})

最新更新