我有一个父组件App
它有一个按钮。单击按钮时,它将调用axios
以获取帖子,然后呈现帖子项目。App
有一个子组件Post
,Post
有一个子组件ListItem
。在我的应用程序测试文件中,我已经测试了 axios 可以在单击按钮后正确加载。但是,我无法测试渲染的内容。它找不到data-testid
:Unable 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")
})
})